import React, { useEffect, useRef, useState } from 'react';
import * as echarts from 'echarts';
import { DatabaseOutlined, FileOutlined, SyncOutlined, CheckCircleFilled, CloseCircleFilled, SettingOutlined } from '@ant-design/icons';
import { DatePicker, Table, Modal, Button, message, Select, ConfigProvider, Switch, Tag, Tooltip, Radio, Spin, Empty } from 'antd';
import 'antd/dist/reset.css';
import './Dashboard.css';
import * as XLSX from 'xlsx';
import { saveAs } from 'file-saver';
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
import { CSSTransition, SwitchTransition } from 'react-transition-group';
import { 
  getDataArchivingList, 
  DataArchivingItem, 
  getDataArchivingStats, 
  DataArchivingStatItem,
  getSyncSpeed,
  SyncSpeedItem,
  getDataRelease,
  DataReleaseItem
} from '../api/dashboard';
import zhCN from 'antd/locale/zh_CN';
import { XMLParser } from 'fast-xml-parser';
import axios from 'axios';
import { formatDataSize, formatDataSizeObject, formatFileCount, DataSizeUnit, convertFromBytes } from '../utils/formatUtils';
import ReleaseDetailModal from '../components/ReleaseDetailModal';

const { MonthPicker, RangePicker } = DatePicker;

const getCircleClass = (percentage: number) => {
  if (percentage > 85) return 'circle high';
  if (percentage > 50) return 'circle medium';
  return 'circle low';
};

const CircularProgress = ({ percentage }: { percentage: number }) => {
  const roundedPercentage = Math.round(percentage);
  return (
    <svg viewBox="0 0 36 36" className="circular-chart">
      <path className="circle-bg"
        d="M18 2.0845
          a 15.9155 15.9155 0 0 1 0 31.831
          a 15.9155 15.9155 0 0 1 0 -31.831"
      />
      <path className={getCircleClass(roundedPercentage)}
        strokeDasharray={`${roundedPercentage}, 100`}
        d="M18 2.0845
          a 15.9155 15.9155 0 0 1 0 31.831
          a 15.9155 15.9155 0 0 1 0 -31.831"
      />
      <text x="18" y="20.35" className="percentage">{roundedPercentage}%</text>
    </svg>
  );
};

const TASKS = ['CE-1', 'CE-2', 'CE-3', 'CE-4', 'CE-5', 'CE-6', 'TW-1', 'TW-2'];

// 开发环境下控制是否使用真实数据的常量 - 供开发人员使用
const USE_REAL_DATA = true; // 设置为 true 使用真实接口数据，false 使用模拟数据

// 添加mock数据开关和模拟数据生成函数
const USE_MOCK_SYNC_SPEED = false; // 设置为true使用模拟数据，false使用真实接口数据

// 调整模拟数据的初始值和变化幅度
const INITIAL_SPEED = {
  GRAS3: 50,
  GRAS4: 30,
  GRAS5: 20
};

// 生成初始模拟数据，确保组件挂载时立即有数据显示
const generateInitialSyncData = () => {
  // 生成过去5分钟的时间点(每30秒一个点)
  const timestamps: string[] = [];
  const now = dayjs();
  for (let i = 0; i < 10; i++) {
    timestamps.unshift(now.subtract((9 - i) * 30, 'second').format('HH:mm:ss'));
  }
  
  // 生成初始数据曲线
  const generateDataPoints = (base: number) => {
    const dataPoints: number[] = [];
    let lastValue = base;
    for (let i = 0; i < 10; i++) {
      // 生成上下波动20%的随机值
      const randomFactor = 0.8 + Math.random() * 0.4; // 0.8 ~ 1.2
      lastValue = Math.max(5, Math.round(lastValue * randomFactor));
      dataPoints.push(lastValue);
    }
    return dataPoints;
  };
  
  return {
    timestamps,
    GRAS3: generateDataPoints(INITIAL_SPEED.GRAS3),
    GRAS4: generateDataPoints(INITIAL_SPEED.GRAS4),
    GRAS5: generateDataPoints(INITIAL_SPEED.GRAS5)
  };
};

// 获取浏览器滚动条宽度
const getScrollbarWidth = () => {
  // 创建一个带滚动条的临时元素
  const outer = document.createElement('div');
  outer.style.visibility = 'hidden';
  outer.style.overflow = 'scroll';
  (outer.style as any).msOverflowStyle = 'scrollbar'; // IE专用属性
  document.body.appendChild(outer);

  const inner = document.createElement('div');
  outer.appendChild(inner);

  const scrollbarWidth = outer.offsetWidth - inner.offsetWidth;
  outer.parentNode?.removeChild(outer);

  return scrollbarWidth;
};

// 磁盘空间数据接口定义
interface DiskSpaceItem {
  ISMON: number;      // 是否监控（1=监控，0=不监控）
  NAME: string;       // 名称
  PATH: string;       // 路径
  rate: number;       // 使用率百分比
}

const Dashboard: React.FC = () => {
  const dataStorageChartRef = useRef<HTMLDivElement>(null);
  const dataDistributionChartRef = useRef<HTMLDivElement>(null);
  const dataStorageChartInstanceRef = useRef<echarts.ECharts | null>(null);
  const dataDistributionChartInstanceRef = useRef<echarts.ECharts | null>(null);

  // 新增：任务多选状态
  const [selectedTasks, setSelectedTasks] = useState<string[]>(['TW-2']);
  // 新增：当月/当年选项状态
  const [dateType, setDateType] = useState<'month' | 'year'>('month');
  
  // 新增：添加数据存储趋势图的数据状态
  const [storageChartData, setStorageChartData] = useState<{
    xAxisData: string[];
    dataTotal: number[];
    dataFile: number[];
    validDataEndIndex?: number;
    originalDataTotal?: number[];
  }>({
    xAxisData: [],
    dataTotal: [],
    dataFile: []
  });
  
  // 新增：添加图表数据加载状态
  const [chartLoading, setChartLoading] = useState<boolean>(false);
  
  // 新增：导出报表弹窗状态
  const [exportModalVisible, setExportModalVisible] = useState(false);
  
  // 导出选项弹窗状态
  const [exportOptionsModalVisible, setExportOptionsModalVisible] = useState(false);
  // 导出时间类型选择 ('archive': 按归档时间, 'collection': 按采集时间)
  const [exportTimeType, setExportTimeType] = useState<'archive' | 'collection'>('archive');
  
  // 新增：导出报表文件列表数据
  const exportFileData = [
    { id: 1, fileName: 'example.txt', filePath: '/path/to/example.txt', fileSize: '2.5', taskType: 'TW1', originType: 'RAW', targetType: 'RAW', completeTime: '2025-03-27 14:00', status: '成功', failReason: '-', storage: 'DPS' },
    { id: 2, fileName: 'file2.cav', filePath: '/archive/2024/03/file2.cav', fileSize: '1.2', taskType: 'TW1', originType: 'RAW', targetType: 'RAW', completeTime: '2025-03-27 15:00', status: '成功', failReason: '-', storage: 'OMS' },
    { id: 3, fileName: 'file3.txt', filePath: '/archive/2024/03/file3.txt', fileSize: '1.2', taskType: 'TW1', originType: 'RAW', targetType: 'RAW', completeTime: '2025-03-27 15:00', status: '成功', failReason: '-', storage: 'OMS' },
    { id: 4, fileName: 'file5.xml', filePath: '/archive/2024/03/file5.xml', fileSize: '1.2', taskType: 'TW1', originType: 'MOSIR', targetType: '0B', completeTime: '2025-03-27 15:00', status: '成功', failReason: '-', storage: 'OMS' },
    { id: 5, fileName: 'report1.pdf', filePath: '/path/to/report1.pdf', fileSize: '1.2', taskType: 'TW1', originType: 'MOSIR', targetType: '2A', completeTime: '2025-03-27 15:00', status: '失败', failReason: '磁盘空间不足', storage: 'OMS' },
    { id: 6, fileName: 'file5.xml', filePath: '/archive/2024/03/file6.xml', fileSize: '1.2', taskType: 'TW1', originType: 'MOSIR', targetType: '0B', completeTime: '2025-03-27 15:00', status: '成功', failReason: '磁盘空间不足', storage: 'OMS' },
    { id: 7, fileName: 'report2.pdf', filePath: '/path/to/report2.pdf', fileSize: '1.2', taskType: 'TW1', originType: 'MOSIR', targetType: '2A', completeTime: '2025-03-27 15:00', status: '失败', failReason: '磁盘空间不足', storage: 'OMS' },
    { id: 8, fileName: 'file5.xml', filePath: '/archive/2024/03/file5.xml', fileSize: '1.2', taskType: 'TW1', originType: 'MOSIR', targetType: '01', completeTime: '2025-03-27 15:00', status: '成功', failReason: '-', storage: 'OMS' },
    { id: 9, fileName: 'report3.pdf', filePath: '/path/to/report3.pdf', fileSize: '1.2', taskType: 'TW1', originType: 'MOSIR', targetType: '2B', completeTime: '2025-03-27 15:00', status: '失败', failReason: '磁盘空间不足', storage: 'OMS' },
    { id: 10, fileName: 'report3.pdf', filePath: '/path/to/report3.pdf', fileSize: '1.2', taskType: 'TW1', originType: 'MOSIR', targetType: '2B', completeTime: '2025-03-27 15:00', status: '失败', failReason: '磁盘空间不足', storage: 'OMS' }
  ];

  // 分页状态
  const [exportCurrentPage, setExportCurrentPage] = useState(1);
  const [exportPageSize, setExportPageSize] = useState(10);
  const [exportPageJump, setExportPageJump] = useState('');

  // 新增：数据发布弹窗状态
  const [showPublishModal, setShowPublishModal] = useState(false);
  // 新增：业务文件系统磁盘空间弹窗状态
  const [showSystemDiskModal, setShowSystemDiskModal] = useState(false);
  
  // 磁盘空间数据状态
  const [systemDisks, setSystemDisks] = useState<DiskSpaceItem[]>([]);
  const [diskSpaceLoading, setDiskSpaceLoading] = useState(false);

  // 计算按钮颜色class
  let systemDiskBtnClass = 'export-btn';
  if (systemDisks.some(d => d.rate > 85)) {
    systemDiskBtnClass += ' danger';
  } else if (systemDisks.some(d => d.rate > 50)) {
    systemDiskBtnClass += ' warning';
  } else {
    systemDiskBtnClass += ' safe';
  }

  // 新增：选中业务详情
  const [selectedBusiness, setSelectedBusiness] = useState<any>({
    taskId: 'OMS0001',
    initiator: 'OMS',
    endTime: '2025-03-21 14:40:00',
    dataSize: 100,
    fileCount: 1234,
    status: '成功',
    failReason: '--'
  });
  const [selectedBusinessFiles, setSelectedBusinessFiles] = useState<any[]>([
    {
      id: 1,
      fileName: 'example.txt',
      filePath: '/path/to/example.txt',
      fileSize: '2.5',
      taskType: 'TW1',
      originType: 'RAW',
      targetType: 'RAW',
      completeTime: '2025-03-27 14:00',
      status: '成功',
      failReason: '-',
      storage: 'DPS'
    },
    {
      id: 2,
      fileName: 'mock2.csv',
      filePath: '/mock/path/mock2.csv',
      fileSize: '1.8',
      taskType: 'TW1',
      originType: 'RAW',
      targetType: 'RAW',
      completeTime: '2025-03-27 15:00',
      status: '失败',
      failReason: '磁盘空间不足',
      storage: 'OMS'
    }
  ]);

  // 弹窗相关处理函数

  const handleExportModalCancel = () => {
    setExportModalVisible(false);
  };

  const [exportLoading, setExportLoading] = useState(false);

  // 多任务导出进度相关状态
  const [exportingTasks, setExportingTasks] = useState<{
    task: string;
    taskName: string; // 新增：任务显示名称
    status: 'waiting' | 'exporting' | 'success' | 'failed';
    message?: string;
    progress?: number; // 新增：进度百分比
  }[]>([]);
  const [isExporting, setIsExporting] = useState(false);
  // 新增：专门控制批量导出进度弹窗的状态
  const [exportProgressVisible, setExportProgressVisible] = useState(false);
  // 新增：导出时间范围显示
  const [exportTimeRange, setExportTimeRange] = useState<string>('');

  const handleExportReport = () => {
    if (!selectedTasks.length) {
      message.warning('请先选择任务');
      return;
    }
    // 打开导出选项弹窗
    setExportOptionsModalVisible(true);
  };

  // 新增：处理导出确认的函数，包含原来 handleExportReport 的所有逻辑
  const handleExportConfirm = async () => {
    // 关闭选项弹窗
    setExportOptionsModalVisible(false);
    
    // 根据活跃的时间模式计算时间区间
    let st = '', et = '';
    let displayTimeRange = '';
    
    if (activeTimeMode === 'custom' && archiveChartDateRange[0] && archiveChartDateRange[1]) {
      // 自定义模式：使用选择的日期范围
      st = dayjs(archiveChartDateRange[0]).format('YYYY-MM-DD HH:mm:ss');
      et = dayjs(archiveChartDateRange[1]).format('YYYY-MM-DD HH:mm:ss');
      displayTimeRange = `${dayjs(archiveChartDateRange[0]).format('YYYY-MM-DD')} 至 ${dayjs(archiveChartDateRange[1]).format('YYYY-MM-DD')}`;
    } else if (activeTimeMode === 'year') {
      // 年份模式：根据dateType和selectedYear计算
      if (dateType === 'year') {
        st = `${selectedYear}-01-01 00:00:00`;
        et = `${selectedYear}-12-31 23:59:59`;
        displayTimeRange = `${selectedYear}年全年`;
      } else {
        const month = dayjs().month() + 1;
        st = `${selectedYear}-${String(month).padStart(2, '0')}-01 00:00:00`;
        et = dayjs(`${selectedYear}-${String(month).padStart(2, '0')}-01`).endOf('month').format('YYYY-MM-DD 23:59:59');
        displayTimeRange = `${selectedYear}年${month}月`;
      }
    } else {
      // 默认情况或无效状态：使用当月
      const month = dayjs().month() + 1;
      st = `${selectedYear}-${String(month).padStart(2, '0')}-01 00:00:00`;
      et = dayjs(`${selectedYear}-${String(month).padStart(2, '0')}-01`).endOf('month').format('YYYY-MM-DD 23:59:59');
      displayTimeRange = `${selectedYear}年${month}月`;
    }

    // 根据导出时间类型在显示中添加说明
    const timeTypeText = exportTimeType === 'archive' ? '按归档时间' : '按采集时间';
    setExportTimeRange(`${displayTimeRange} (${timeTypeText})`);

    // 初始化导出状态
    const taskStatus = selectedTasks.map(task => ({
      task: task.replace(/-/g, ''),
      taskName: task, // 保留原始任务名称用于显示
      status: 'waiting' as const,
      progress: 0
    }));
    setExportingTasks(taskStatus);
    setIsExporting(true);
    setExportProgressVisible(true); // 只控制进度弹窗

    // 根据时间类型选择API端点
    const apiEndpoint = exportTimeType === 'archive' 
      ? '/-/bin.dataStat.download_data_stat_by_task'  // 原API
      : '/-/bin.dataStat.download_data_stat_by_cj';   // 新API

    for (let i = 0; i < selectedTasks.length; i++) {
      const originalTask = selectedTasks[i];
      const task = originalTask.replace(/-/g, '');
      
      // 更新状态为导出中
      setExportingTasks(prev => prev.map(t =>
        t.task === task ? { ...t, status: 'exporting', progress: 10 } : t
      ));

      try {
        const params = { task, st, et };
        const API_BASE_URL = import.meta.env.VITE_API_BASE_URL;
        
        // 模拟进度更新
        setExportingTasks(prev => prev.map(t =>
          t.task === task ? { ...t, progress: 30 } : t
        ));
        
        // 使用选择的API端点
        const response = await axios.post(
          `${API_BASE_URL}${apiEndpoint}`,
          params,
          {
            responseType: 'blob',
            headers: {
              'token': localStorage.getItem('token') || ''
            }
          }
        );
        
        // 更新进度
        setExportingTasks(prev => prev.map(t =>
          t.task === task ? { ...t, progress: 70 } : t
        ));
        
        // 生成新的文件名格式，包含时间类型标识
        const startDate = dayjs(st).format('YYYYMMDD');
        const endDate = dayjs(et).format('YYYYMMDD');
        let fileName = `数据归档报表_${originalTask}_${startDate}-${endDate}_${timeTypeText}.xlsx`;
        
        const disposition = response.headers['content-disposition'];
        if (disposition) {
          const match = disposition.match(/filename="?([^";]+)"?/);
          if (match) {
            // 如果服务器返回了文件名，仍使用我们的格式
            fileName = `数据归档报表_${originalTask}_${startDate}-${endDate}_${timeTypeText}.xlsx`;
          }
        }
        
        // 更新进度
        setExportingTasks(prev => prev.map(t =>
          t.task === task ? { ...t, progress: 90 } : t
        ));
        
        const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
        if (window.navigator && (window.navigator as any).msSaveOrOpenBlob) {
          (window.navigator as any).msSaveOrOpenBlob(blob, fileName);
        } else {
          const link = document.createElement('a');
          link.href = window.URL.createObjectURL(blob);
          link.download = fileName;
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link);
        }
        
        // 完成
        setExportingTasks(prev => prev.map(t =>
          t.task === task ? { ...t, status: 'success', progress: 100 } : t
        ));
        
        await new Promise(resolve => setTimeout(resolve, 800));
      } catch (err: any) {
        setExportingTasks(prev => prev.map(t =>
          t.task === task ? { ...t, status: 'failed', message: err?.message || '未知错误', progress: 0 } : t
        ));
      }
    }
    setIsExporting(false);
    message.success('所有报表导出完成');
  };

  // 新增：取消导出选项
  const handleExportOptionsCancel = () => {
    setExportOptionsModalVisible(false);
  };

  // 业务运行状态表格分页相关state
  const [currentPage, setCurrentPage] = useState(1);
  const [pageSize, setPageSize] = useState(10);
  // 新增：业务类型筛选状态
  const [businessTypeFilter, setBusinessTypeFilter] = useState('');
  // 新增：发起方、状态、开始时间筛选状态
  const [initiatorFilter, setInitiatorFilter] = useState('全部');
  const [statusFilter, setStatusFilter] = useState('全部');
  // 默认时间范围为当天
  const today = dayjs().endOf('day');
  const sevenDaysAgo = dayjs().subtract(6, 'day').startOf('day');
  const [startTimeRange, setStartTimeRange] = useState<[any, any]>([
    sevenDaysAgo,
    today
  ]);
  // 新增：表格排序状态（接口排序）
  const [sortField, setSortField] = useState<string>('startTime');
  const [sortOrder, setSortOrder] = useState<'ascend' | 'descend' | null>('descend');
  
  // 新增业务数据状态，替换原有的假数据
  const [businessData, setBusinessData] = useState<any[]>([]);
  const [allBusinessData, setAllBusinessData] = useState<any[]>([]); // 保存全量数据
  const [businessTotal, setBusinessTotal] = useState(0);
  const [loading, setLoading] = useState(false);
  
  // 新增统计数据
  const [stats, setStats] = useState({
    totalCount: 0,
    archiveCount: 0,
    callCount: 0,
    backupCount: 0,
    publishCount: 0
  });
  
  // 新增已知的所有发起方列表
  const [allInitiators, setAllInitiators] = useState<string[]>([]);

  // 在组件顶部 state 区域添加年份相关 state
  const currentYear = dayjs().year();
  // 生成默认的年份选项（最近50年），用于下拉列表
  const defaultYearOptions = Array.from({ length: 50 }, (_, i) => currentYear - 25 + i);
  const [selectedYear, setSelectedYear] = useState(currentYear);

  // 新增：数据归档图表的自定义日期区间
  const [archiveChartDateRange, setArchiveChartDateRange] = useState<[any, any]>([null, null]);
  
  // 新增：时间选择模式状态（年份模式或自定义模式）
  const [activeTimeMode, setActiveTimeMode] = useState<'year' | 'custom'>('year');

  // 1. 新增：地面站数据同步实时速率数据状态
  // 用函数生成初始10个时间点和0速率
  const getInitialSyncSpeedData = () => {
    const timestamps: string[] = [];
    const now = dayjs();
    for (let i = 9; i >= 0; i--) {
      timestamps.push(now.subtract(i * 10, 'second').format('HH:mm:ss'));
    }
    return {
      timestamps,
      GRAS3: Array(10).fill(0),
      GRAS4: Array(10).fill(0),
      GRAS5: Array(10).fill(0)
    };
  };
  const [syncSpeedData, setSyncSpeedData] = useState(getInitialSyncSpeedData());
  
  // 新增：同步速率图表加载状态
  const [syncChartLoading, setSyncChartLoading] = useState<boolean>(false);
  
  // 新增：同步速率定时器引用
  const syncSpeedTimerRef = useRef<number | null>(null);

  // 新增：地面站数据同步实时速率详情模态框图表引用
  const syncModalChartRef = useRef<HTMLDivElement>(null);
  const syncModalChartInstanceRef = useRef<echarts.ECharts | null>(null);

  // 新增：存储当前文件名状态
  const [currentFiles, setCurrentFiles] = useState<Record<string, string>>({
    GRAS3: '-',
    GRAS4: '-',
    GRAS5: '-'
  });

  // 1. 新增今日存档数据量和文件数的状态
  const [todayArchiveSizeRaw, setTodayArchiveSizeRaw] = useState<number>(0); // 原始字节数
  const [todayArchiveFileCount, setTodayArchiveFileCount] = useState<number>(0);

  // 新增：本月数据发布统计
  const [releaseLoading, setReleaseLoading] = useState<boolean>(false);
  const [releaseCount, setReleaseCount] = useState<number>(0); // 本月数据发布次数 t
  const [releaseSizeBytes, setReleaseSizeBytes] = useState<number>(0); // 数据量 t_z（按字节理解）
  const [releaseFileCount, setReleaseFileCount] = useState<number>(0); // 文件数 t_f

  // 新增：数据发布详情弹窗相关状态
  const [releaseDetailYear, setReleaseDetailYear] = useState(currentYear);
  const [releaseDetailData, setReleaseDetailData] = useState<any[]>([]);
  const [releaseDetailTotal, setReleaseDetailTotal] = useState<any>(null);
  const [releaseDetailLoading, setReleaseDetailLoading] = useState(false);
  const [scrollbarWidth, setScrollbarWidth] = useState(17); // 动态存储滚动条宽度

  // 新增：数据发布报告详情弹窗状态
  const [showReleaseDetailModal, setShowReleaseDetailModal] = useState(false);
  const [selectedReleaseTaskId, setSelectedReleaseTaskId] = useState<string | null>(null);

  // 新增：详情XML相关state
  const [xmlDetailLoading, setXmlDetailLoading] = useState(false);
  const [xmlDetailError, setXmlDetailError] = useState<string | null>(null);
  const [xmlDetailData, setXmlDetailData] = useState<any>(null);
  const [xmlRawString, setXmlRawString] = useState<string>('');
  const [xmlCollapseOpen, setXmlCollapseOpen] = useState(false);
  const [xmlFilePath, setXmlFilePath] = useState<string>(''); // 新增：存储XML文件路径

  // 在Dashboard组件内，state区域下方添加：
  const tableNodeRef = useRef(null);

  // 1. 在state区域增加单位state
  const [storageUnit, setStorageUnit] = useState<DataSizeUnit>(DataSizeUnit.GB);
  
  // 添加认证状态检查
  const [isAuthenticated, setIsAuthenticated] = useState(false);
  
  // 检查登录状态
  useEffect(() => {
    const token = localStorage.getItem('token');
    const user = localStorage.getItem('user');
    if (token && user) {
      setIsAuthenticated(true);
    }
  }, []);

  // 计算滚动条宽度
  useEffect(() => {
    const width = getScrollbarWidth();
    setScrollbarWidth(width);
  }, []);

  // 联动逻辑：当切换到自定义模式时，根据选中的年份设置默认日期范围
  const setDefaultCustomDateRange = (year: number) => {
    const currentYear = dayjs().year();
    const currentMonth = dayjs().month(); // 0-11
    
    if (year === currentYear) {
      // 当年情况：当年当月到下月
      const startDate = dayjs().year(year).month(currentMonth).startOf('month');
      const endDate = dayjs().year(year).month(currentMonth + 1).endOf('month');
      setArchiveChartDateRange([startDate, endDate]);
    } else {
      // 历史年份情况：该年1月到2月
      const startDate = dayjs().year(year).month(0).startOf('month'); // 1月
      const endDate = dayjs().year(year).month(1).endOf('month'); // 2月
      setArchiveChartDateRange([startDate, endDate]);
    }
  };

  // 切换时间选择模式
  const switchTimeMode = (mode: 'year' | 'custom') => {
    if (mode !== activeTimeMode) {
      setActiveTimeMode(mode);
      if (mode === 'custom') {
        // 切换到自定义模式时，设置默认日期范围
        setDefaultCustomDateRange(selectedYear);
      }
    }
  };

  // 获取数据发布统计（本月）
  const fetchDataRelease = async () => {
    if (!isAuthenticated) return;
    setReleaseLoading(true);
    try {
      const res = await getDataRelease();
      if (res.code === 200 && Array.isArray(res.data)) {
        // 累加返回数组中的各项（稳妥处理）
        const totalCount = res.data.reduce((acc, item) => acc + (Number(item.t) || 0), 0);
        const totalSize = res.data.reduce((acc, item) => acc + (Number(item.t_z) || 0), 0);
        const totalFiles = res.data.reduce((acc, item) => acc + (Number((item as DataReleaseItem).t_f) || 0), 0);
        setReleaseCount(totalCount);
        setReleaseSizeBytes(totalSize);
        setReleaseFileCount(totalFiles);
      } else {
        message.error('获取数据发布数据失败');
      }
    } catch (e) {
      console.error('获取数据发布数据出错:', e);
      message.error('获取数据发布数据出错');
    } finally {
      setReleaseLoading(false);
    }
  };

  // 获取年度数据发布详情
  const fetchDataReleaseByYear = async (year: number) => {
    setReleaseDetailLoading(true);
    try {
      const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || '';
      const token = localStorage.getItem('token') || '';

      const response = await fetch(`${API_BASE_URL}/-/bin.dataArchiving.get_data_release_by_year`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'token': token
        },
        body: JSON.stringify({ year: year.toString() })
      });

      const result = await response.json();
      if (result.code === 200 && Array.isArray(result.data)) {
        // 处理数据，将月份格式化
        const formattedData = result.data.map((item: any) => ({
          month: `${item.m.substring(0, 4)}年${parseInt(item.m.substring(4, 6))}月`,
          publishCount: item.t || 0,
          fileCount: item.t_f || 0,
          dataSize: formatDataSize(item.t_z || 0),
          rawDataSize: item.t_z || 0
        }));
        setReleaseDetailData(formattedData);

        // 处理合计数据
        if (result.total) {
          const totalData = {
            month: '合计',
            publishCount: result.total.t || 0,
            fileCount: result.total.t_f || 0,
            dataSize: formatDataSize(result.total.t_z || 0),
            rawDataSize: result.total.t_z || 0
          };
          setReleaseDetailTotal(totalData);
        } else {
          setReleaseDetailTotal(null);
        }
      } else {
        message.error('获取年度数据发布详情失败');
        setReleaseDetailTotal(null);
      }
    } catch (error) {
      console.error('获取年度数据发布详情出错:', error);
      message.error('获取年度数据发布详情出错');
    } finally {
      setReleaseDetailLoading(false);
    }
  };

  // 获取业务运行数据
  const fetchBusinessData = async () => {
    setLoading(true);
    try {
      // 构建查询参数 - 传递实际的筛选条件给后端
      const params: any = {
        page: currentPage,
        ps: pageSize,
        source: initiatorFilter === '全部' ? '' : initiatorFilter,  // 发起方筛选：OMS/DPS/手动
        status: statusFilter === '全部' ? '' : statusFilter,        // 状态筛选
        type: businessTypeFilter,   // 业务类型筛选：空字符串(全部)/DATA_ARCHIVING/D4/DATA_BACKUP/DATA_RELEASE
        st: startTimeRange[0] ? dayjs(startTimeRange[0]).format('YYYYMMDDHHmmss') : '',
        et: startTimeRange[1] ? dayjs(startTimeRange[1]).format('YYYYMMDDHHmmss') : ''
      };
      // 新增：排序参数
      if (sortField && sortOrder) {
        // col字段名与后端约定：startTime -> ctime, endTime -> utime
        params.col = sortField === 'startTime' ? 'ctime' : (sortField === 'endTime' ? 'utime' : '');
        params.sort = sortOrder === 'ascend' ? 'asc' : 'desc';
      }
      
      const response = await getDataArchivingList(params);
      
      if (response.code === 200) {
        // 转换数据格式
        const formattedData = response.data.map((item, index) => ({
          key: index + 1, // 不再依赖分页计算key
          taskId: item.rcmd_num,
          taskType: item.rtype,
          initiator: item.rsource_sys,
          startTime: item.ctime,
          endTime: item.utime,
          dataSize: {
            success: parseFloat(item.rf_success_size), // 单位B
            total: parseFloat(item.total_size)        // 单位B
          }, // 成功/总数（B）
          fileCount: {
            success: item.rf_success,
            fail: item.rf_fail,
            total: item.rf_num
          }, // 成功/失败/总数
          status: item.rstatus === '1' ? '成功' : (item.rstatus === '0' ? '运行中' : '失败'),
          failReason: item.rf_fail_reason || '--',
          rawData: item // 保存原始数据，方便后续使用
        }));
        
        // 保存当前页数据
        setAllBusinessData(formattedData);

        // 设置数据总数（来自后端）
        setBusinessTotal(response.total || formattedData.length);

        // 处理并显示数据
        filterBusinessData(formattedData);
        
        // 更新发起方列表
        const initiators = Array.from(new Set(response.data.map(item => item.rsource_sys)));
        setAllInitiators(initiators);

        // 统计数据现在由fetchBusinessStatistics独立处理，不在这里更新
      } else {
        message.error('获取业务运行数据失败');
      }
    } catch (error) {
      console.error('获取业务运行数据出错:', error);
      message.error('获取业务运行数据出错');
    } finally {
      setLoading(false);
    }
  };
  
  // 更新统计数据
  const updateStatistics = (total: number, typeCount?: Array<{t: number; rtype: string}>) => {
    // 从 type_count 中提取各类型的数量，建立映射
    const typeCountMap: Record<string, number> = {};
    if (typeCount) {
      typeCount.forEach(item => {
        typeCountMap[item.rtype] = item.t;
      });
    }

    // 根据映射获取各类型数量，如果不存在则默认为0
    setStats({
      totalCount: total || 0,
      archiveCount: typeCountMap['DATA_ARCHIVING'] || 0,
      callCount: typeCountMap['D4'] || 0,
      backupCount: typeCountMap['DATA_BACKUP'] || 0,
      publishCount: typeCountMap['DATA_RELEASE'] || 0
    });
  };
  
  // 新增：处理后端返回的数据（后端已经完成筛选）
  const filterBusinessData = (data = allBusinessData) => {
    // 后端已经根据type、source、status参数完成筛选
    // 前端只需要处理序号重新计算
    let filteredData = [...data];

    // 更新表格数据，并重新计算序号
    const displayData = filteredData.map((item, index) => ({
      ...item,
      key: (currentPage - 1) * pageSize + index + 1
    }));

    setBusinessData(displayData);
    // 注意：总数由fetchBusinessData从后端response.total获取，不在这里设置
  };
  
  // 获取磁盘空间数据
  const fetchDiskSpaceData = async () => {
    setDiskSpaceLoading(true);
    try {
      const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || '';
      const token = localStorage.getItem('token') || '';
      
      const response = await fetch(`${API_BASE_URL}/-/bin.diskSpaceMon.get_disk_space`, {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
          'token': token
        }
      });
      
      const result = await response.json();
      if (result.code === 200 && result.data?.SYNC) {
        setSystemDisks(result.data.SYNC);
      } else {
        message.error('获取磁盘空间数据失败');
      }
    } catch (error) {
      console.error('获取磁盘空间数据失败:', error);
      message.error('获取磁盘空间数据失败');
    } finally {
      setDiskSpaceLoading(false);
    }
  };

  // 获取业务统计数据（独立于筛选条件）
  const fetchBusinessStatistics = async () => {
    try {
      // 构建查询参数 - 获取全部数据用于统计
      const params: any = {
        page: 1,
        ps: 1,  // 只需要统计数据，不需要实际数据
        source: '',  // 获取所有来源
        status: '',  // 获取所有状态
        type: '',    // 获取所有类型
        st: startTimeRange[0] ? dayjs(startTimeRange[0]).format('YYYYMMDDHHmmss') : '',
        et: startTimeRange[1] ? dayjs(startTimeRange[1]).format('YYYYMMDDHHmmss') : ''
      };

      const response = await getDataArchivingList(params);

      if (response.code === 200) {
        // 更新统计数据，使用total和type_count
        updateStatistics(response.total, response.type_count);
      }
    } catch (error) {
      console.error('获取业务统计数据出错:', error);
      // 出错时设置为0
      setStats({
        totalCount: 0,
        archiveCount: 0,
        callCount: 0,
        backupCount: 0,
        publishCount: 0
      });
    }
  };

  // 清理磁盘空间
  const handleDiskClean = async (path: string, name: string) => {
    Modal.confirm({
      title: '确认清理',
      content: `确定要清理 ${name} (${path}) 的磁盘空间吗？`,
      okText: '确定',
      cancelText: '取消',
      onOk: async () => {
        try {
          const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || '';
          const token = localStorage.getItem('token') || '';
          
          const response = await fetch(`${API_BASE_URL}/-/bin.diskSpaceMon.clean_path_data`, {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
              'token': token
            },
            body: JSON.stringify({ path })
          });
          
          const result = await response.json();
          if (result.code === 200) {
            message.success(result.msg || '清理任务已开始');
            // 刷新数据
            fetchDiskSpaceData();
          } else {
            message.error(result.msg || '清理失败');
          }
        } catch (error) {
          console.error('清理请求失败:', error);
          message.error('清理请求失败');
        }
      }
    });
  };
  
  // 获取统计数据（初次加载和时间范围改变时）
  useEffect(() => {
    if (!isAuthenticated) return; // 未登录不执行
    fetchBusinessStatistics();
  }, [isAuthenticated, startTimeRange]);

  // 当分页、筛选、排序改变时重新请求数据
  useEffect(() => {
    if (!isAuthenticated) return; // 未登录不执行
    fetchBusinessData();
  }, [isAuthenticated, currentPage, pageSize, businessTypeFilter, initiatorFilter, statusFilter, startTimeRange, sortField, sortOrder]);
  
  // 当磁盘空间弹窗打开时加载数据
  useEffect(() => {
    if (showSystemDiskModal) {
      fetchDiskSpaceData();
    }
  }, [showSystemDiskModal]);

  // 自动刷新相关
  const AUTO_REFRESH_INTERVAL = 10000; // 10秒

  // 自动刷新定时器
  useEffect(() => {
    if (!isAuthenticated) return; // 未登录不执行
    const timer = setInterval(() => {
      fetchBusinessData();
    }, AUTO_REFRESH_INTERVAL);
    return () => clearInterval(timer);
  }, [isAuthenticated, currentPage, pageSize, businessTypeFilter, initiatorFilter, statusFilter, startTimeRange, sortField, sortOrder]);

  // 新增：获取数据归档统计函数
  const fetchDataArchivingStats = async () => {
    setChartLoading(true);

    // 清理现有图表状态，避免显示旧数据
    if (dataStorageChartInstanceRef.current) {
      dataStorageChartInstanceRef.current.showLoading({
        text: '正在获取数据...',
        color: '#1890ff',
        textColor: '#1890ff',
        maskColor: 'rgba(255, 255, 255, 0.8)'
      });
    }

    try {
      let sd, ed, flag;
      
      if (activeTimeMode === 'custom' && archiveChartDateRange[0] && archiveChartDateRange[1]) {
        // 自定义模式：使用选择的日期范围
        sd = dayjs(archiveChartDateRange[0]).format('YYYY-MM-DD');
        ed = dayjs(archiveChartDateRange[1]).format('YYYY-MM-DD');
        
        // 计算时间段长度，大于2个月传month，否则传day
        const startDate = dayjs(archiveChartDateRange[0]);
        const endDate = dayjs(archiveChartDateRange[1]);
        const diffInMonths = endDate.diff(startDate, 'month', true); // true 表示精确计算包含小数
        
        flag = diffInMonths > 2 ? 'month' : 'day';
      } else if (activeTimeMode === 'year') {
        // 年份模式：根据dateType和selectedYear计算
        if (dateType === 'year') {
          sd = `${selectedYear}-01-01`;
          ed = `${selectedYear}-12-31`;
          flag = 'month';
        } else {
          // 当月
          const selectedMonth = dayjs().month() + 1; // dayjs 月份从 0 开始
          sd = `${selectedYear}-${String(selectedMonth).padStart(2, '0')}-01`;
          ed = dayjs(`${selectedYear}-${String(selectedMonth).padStart(2, '0')}-01`).endOf('month').format('YYYY-MM-DD');
          flag = 'day';
        }
      } else {
        // 默认情况：使用当月
        const selectedMonth = dayjs().month() + 1;
        sd = `${selectedYear}-${String(selectedMonth).padStart(2, '0')}-01`;
        ed = dayjs(`${selectedYear}-${String(selectedMonth).padStart(2, '0')}-01`).endOf('month').format('YYYY-MM-DD');
        flag = 'day';
      }
      // 构建 task 参数
      const task = selectedTasks.length === TASKS.length ? 'ALL' : selectedTasks.join(',');
      const params = {
        sd,
        ed,
        task,
        flag
      };
      const response = await getDataArchivingStats(params);
      if (response.code === 200) {
        // 1. 生成完整x轴
        let xAxisData: string[] = [];
        let dataTotal: number[] = [];
        let dataFile: number[] = [];
        let dataMap: Record<string, {fz: number, ft: number}> = {};
        
        if (flag === 'month') {
          // 按月显示：生成月份轴
          if (archiveChartDateRange[0] && archiveChartDateRange[1]) {
            // 自定义时间段按月显示
            const startMonth = dayjs(archiveChartDateRange[0]);
            const endMonth = dayjs(archiveChartDateRange[1]);
            const monthsCount = endMonth.diff(startMonth, 'month') + 1;
            
            xAxisData = Array.from({ length: monthsCount }, (_, i) => {
              const currentMonth = startMonth.add(i, 'month');
              return currentMonth.format('YYYY-MM');
            });
            
            // 构建数据映射
            response.data.forEach(item => {
              const itemMonth = dayjs(item.rdate).format('YYYY-MM');
              const monthIndex = xAxisData.indexOf(itemMonth);
              if (monthIndex !== -1) {
                dataMap[monthIndex] = { fz: item.fz, ft: parseInt(item.ft) };
              }
            });
            
            // 补齐数据
            for (let i = 0; i < monthsCount; i++) {
              if (dataMap[i]) {
                dataTotal.push(dataMap[i].fz);
                dataFile.push(dataMap[i].ft);
              } else {
                dataTotal.push(0);
                dataFile.push(0);
              }
            }
          } else {
            // 年视图：显示当年完整12个月
            const maxMonth = 12;
            xAxisData = Array.from({ length: maxMonth }, (_, i) => `${i + 1}月`);
            // 构建数据映射
            response.data.forEach(item => {
              const month = dayjs(item.rdate).month(); // 0~11
              dataMap[month] = { fz: item.fz, ft: parseInt(item.ft) };
            });
            // 补齐数据
            for (let i = 0; i < maxMonth; i++) {
              if (dataMap[i]) {
                dataTotal.push(dataMap[i].fz); // 原始B（字节）数据
                dataFile.push(dataMap[i].ft);
              } else {
                dataTotal.push(0);
                dataFile.push(0);
              }
            }
          }
        } else {
          // 按天显示
          if (archiveChartDateRange[0] && archiveChartDateRange[1]) {
            // 自定义时间段按天显示
            const startDate = dayjs(archiveChartDateRange[0]);
            const endDate = dayjs(archiveChartDateRange[1]);
            const daysCount = endDate.diff(startDate, 'day') + 1;
            
            xAxisData = Array.from({ length: daysCount }, (_, i) => {
              const currentDate = startDate.add(i, 'day');
              return currentDate.format('MM-DD');
            });
            
            // 构建数据映射
            response.data.forEach(item => {
              const itemDate = dayjs(item.rdate);
              const dayIndex = itemDate.diff(startDate, 'day');
              if (dayIndex >= 0 && dayIndex < daysCount) {
                dataMap[dayIndex] = { fz: item.fz, ft: parseInt(item.ft) };
              }
            });
            
            // 补齐数据
            for (let i = 0; i < daysCount; i++) {
              if (dataMap[i]) {
                dataTotal.push(dataMap[i].fz);
                dataFile.push(dataMap[i].ft);
              } else {
                dataTotal.push(0);
                dataFile.push(0);
              }
            }
          } else {
            // 月视图：显示当月完整日期
            const daysInMonth = dayjs(sd).daysInMonth();
            const maxDay = daysInMonth;
            xAxisData = Array.from({ length: maxDay }, (_, i) => String(i + 1).padStart(2, '0'));
            // 构建数据映射
            response.data.forEach(item => {
              const day = dayjs(item.rdate).date(); // 1~31
              dataMap[day] = { fz: item.fz, ft: parseInt(item.ft) };
            });
            // 补齐数据
            for (let i = 1; i <= maxDay; i++) {
              if (dataMap[i]) {
                dataTotal.push(dataMap[i].fz); // 原始B（字节）数据
                dataFile.push(dataMap[i].ft);
              } else {
                dataTotal.push(0);
                dataFile.push(0);
              }
            }
          }
        }
        
        // 智能判断最佳单位：基于最大值确定统一单位
        const maxValue = Math.max(...dataTotal);
        const { unit: bestUnit } = formatDataSizeObject(maxValue);
        
        // 将所有数据转换为最佳单位（使用convertFromBytes确保统一单位）
        const convertedDataTotal = dataTotal.map(value => {
          return convertFromBytes(value, bestUnit, 2);
        });
        
        // 计算有效数据范围（排除未来日期）
        const today = dayjs();
        let validDataEndIndex = dataTotal.length - 1;
        
        if (flag === 'day') {
          // 按天显示：如果是当月，限制到当前日期
          if (activeTimeMode === 'year' && dateType === 'month') {
            const currentMonth = dayjs(sd);
            if (currentMonth.isSame(today, 'month') && currentMonth.isSame(today, 'year')) {
              validDataEndIndex = today.date() - 1; // 数组索引从0开始，日期从1开始
            }
          }
        } else if (flag === 'month') {
          // 按月显示：如果是当年，限制到当前月份
          if (activeTimeMode === 'year' && dateType === 'year') {
            const selectedYearValue = parseInt(selectedYear.toString());
            if (selectedYearValue === today.year()) {
              validDataEndIndex = today.month(); // dayjs月份从0开始，正好匹配数组索引
            }
          }
        }

        setStorageUnit(bestUnit);
        setStorageChartData({
          xAxisData,
          dataTotal: convertedDataTotal,
          dataFile,
          validDataEndIndex, // 新增：有效数据结束索引
          originalDataTotal: dataTotal // 新增：保留原始数据用于计算
        });
      } else {
        message.error('获取数据归档统计失败');
      }
    } catch (error) {
      console.error('获取数据归档统计出错:', error);
      message.error('获取数据归档统计出错');
    } finally {
      setChartLoading(false);
    }
  };
  
  // 当年份变化时，如果是自定义模式，更新默认日期范围
  useEffect(() => {
    if (activeTimeMode === 'custom' && selectedYear) {
      setDefaultCustomDateRange(selectedYear);
    }
  }, [selectedYear, activeTimeMode]);

  // 当筛选条件改变时，重新获取数据
  useEffect(() => {
    if (!isAuthenticated) return; // 未登录不执行
    fetchDataArchivingStats();
  }, [isAuthenticated, dateType, selectedYear, selectedTasks, archiveChartDateRange, activeTimeMode]);

  // 在认证后获取一次数据发布统计，并按固定间隔刷新
  useEffect(() => {
    if (!isAuthenticated) return;
    fetchDataRelease();
    const timer = window.setInterval(fetchDataRelease, AUTO_REFRESH_INTERVAL);
    return () => window.clearInterval(timer);
  }, [isAuthenticated]);

  // 修改原有的数据存储趋势图表渲染函数
  useEffect(() => {
    if (!isAuthenticated) return; // 未登录不执行
    
    // 如果正在加载数据，显示loading状态
    if (chartLoading) {
      if (dataStorageChartInstanceRef.current) {
        dataStorageChartInstanceRef.current.showLoading({
          text: '数据加载中...',
          color: '#1890ff',
          textColor: '#1890ff',
          maskColor: 'rgba(255, 255, 255, 0.8)'
        });
      }
      return;
    }
    
    // 数据存储趋势图表渲染
    if (dataStorageChartRef.current) {
      // 清理现有图表实例
      if (dataStorageChartInstanceRef.current) {
        dataStorageChartInstanceRef.current.hideLoading();
        dataStorageChartInstanceRef.current.dispose();
      }
      
      // 创建新的图表实例
      const chart = echarts.init(dataStorageChartRef.current);
      dataStorageChartInstanceRef.current = chart;
      // 计算自定义markPoint，排除未来日期的0值
      let markPointDataTotal: any[] = [];
      let markPointDataFile: any[] = [];
      
      if (storageChartData.dataTotal.length > 0) {
        const validEndIndex = storageChartData.validDataEndIndex ?? storageChartData.dataTotal.length - 1;
        const validDataTotal = storageChartData.dataTotal.slice(0, validEndIndex + 1);
        const validDataFile = storageChartData.dataFile.slice(0, validEndIndex + 1);
        
        // 计算最大值
        if (validDataTotal.length > 0) {
          const maxTotalValue = Math.max(...validDataTotal);
          const maxTotalIndex = storageChartData.dataTotal.indexOf(maxTotalValue);
          if (maxTotalIndex !== -1) {
            markPointDataTotal.push({
              xAxis: maxTotalIndex,
              yAxis: maxTotalValue,
              name: '最大值'
            });
          }
        }
        
        // 计算最小值（排除0值）
        const nonZeroValidDataTotal = validDataTotal.filter(v => v > 0);
        if (nonZeroValidDataTotal.length > 0) {
          const minTotalValue = Math.min(...nonZeroValidDataTotal);
          const minTotalIndex = storageChartData.dataTotal.indexOf(minTotalValue);
          if (minTotalIndex !== -1 && minTotalIndex <= validEndIndex) {
            markPointDataTotal.push({
              xAxis: minTotalIndex,
              yAxis: minTotalValue,
              name: '最小值'
            });
          }
        }
        
        // 文件数的markPoint计算
        if (validDataFile.length > 0) {
          const maxFileValue = Math.max(...validDataFile);
          const maxFileIndex = storageChartData.dataFile.indexOf(maxFileValue);
          if (maxFileIndex !== -1) {
            markPointDataFile.push({
              xAxis: maxFileIndex,
              yAxis: maxFileValue,
              name: '最大值'
            });
          }
          
          // 文件数最小值（排除0值）
          const nonZeroValidDataFile = validDataFile.filter(v => v > 0);
          if (nonZeroValidDataFile.length > 0) {
            const minFileValue = Math.min(...nonZeroValidDataFile);
            const minFileIndex = storageChartData.dataFile.indexOf(minFileValue);
            if (minFileIndex !== -1 && minFileIndex <= validEndIndex) {
              markPointDataFile.push({
                xAxis: minFileIndex,
                yAxis: minFileValue,
                name: '最小值'
              });
            }
          }
        }
      }
      const option = {
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'cross'
          },
          // 优化formatter，让内容更清晰分离
          formatter: (params: Array<{ seriesName: string; marker: string; data: number; axisValue: string; seriesIndex: number; color: string }>) => {
            let str = `<div style="font-weight: bold; margin-bottom: 8px; color: #333; border-bottom: 1px solid #eee; padding-bottom: 4px;">${params[0].axisValue}</div>`;
            let validItemIndex = 0; // 用于跟踪实际显示的项目索引
            params.forEach((item) => {
              // 跳过没有数据的项
              if (item.data == null) {
                return;
              }

              const marginTop = validItemIndex > 0 ? 'margin-top: 6px;' : '';
              if (item.seriesName === '存储总量') {
                str += `<div style="${marginTop} padding: 4px 0; background: rgba(209, 74, 97, 0.1); border-left: 3px solid ${item.color}; padding-left: 8px; border-radius: 2px;">
                  ${item.marker}<span style="font-weight: 600;">${item.seriesName}:</span> <b style="color: ${item.color};">${item.data} ${storageUnit}</b>
                </div>`;
              } else {
                str += `<div style="${marginTop} padding: 4px 0; background: rgba(103, 91, 186, 0.1); border-left: 3px solid ${item.color}; padding-left: 8px; border-radius: 2px;">
                  ${item.marker}<span style="font-weight: 600;">${item.seriesName}:</span> <b style="color: ${item.color};">${formatFileCount(item.data)}</b>
                </div>`;
              }
              validItemIndex++;
            });
            return str;
          },
          // 优化tooltip位置，更智能地避免重叠
          position: function (
            point: number[],
            params: any[],
            dom: HTMLElement,
            rect: any,
            size: { contentSize: number[]; viewSize: number[] }
          ) {
            let pos = [point[0], point[1]];
            const offsetX = 15; // 基础水平偏移
            const offsetY = 15; // 基础垂直偏移
            
            // 检查是否接近边界，进行边界避让
            if (point[0] + size.contentSize[0] + offsetX > size.viewSize[0]) {
              pos[0] = point[0] - size.contentSize[0] - offsetX; // 向左显示
            } else {
              pos[0] = point[0] + offsetX; // 向右显示
            }
            
            if (point[1] + size.contentSize[1] + offsetY > size.viewSize[1]) {
              pos[1] = point[1] - size.contentSize[1] - offsetY; // 向上显示
            } else {
              pos[1] = point[1] + offsetY; // 向下显示
            }
            
            // 当有多个系列且数值相近时，额外错开显示
            if (params && params.length > 1) {
              const values = params.map((p: any) => p.data);
              const maxVal = Math.max(...values);
              const minVal = Math.min(...values);
              // 如果数值差异小于最大值的10%，认为是重叠，进行额外偏移
              if (maxVal > 0 && (maxVal - minVal) / maxVal < 0.1) {
                pos[1] -= 25; // 向上额外偏移
                pos[0] += 20; // 向右额外偏移
              }
            }
            
            return pos;
          },
          backgroundColor: 'rgba(255, 255, 255, 0.95)',
          borderColor: '#ccc',
          borderWidth: 1,
          textStyle: {
            color: '#333',
            fontSize: 13
          },
          extraCssText: 'box-shadow: 0 4px 12px rgba(0,0,0,0.15); border-radius: 6px; padding: 8px 12px;'
        },
        legend: {
          data: ['存储总量', '存储文件数'],
          right: 10,
          top: 0
        },
        grid: {
          left: '4%',
          right: '4%',
          bottom: '5%',
          top: '15%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          boundaryGap: false,
          data: storageChartData.xAxisData
        },
        yAxis: [
          {
            type: 'value',
            name: `存储总量(${storageUnit})`,
            position: 'left',
            // 左轴使用1.5倍最大值，让数据线更分散
            max: function(value: any) {
              return Math.ceil(value.max * 1.5);
            },
            axisLine: {
              show: true,
              lineStyle: {
                color: '#d14a61'
              }
            },
            axisLabel: {
              formatter: '{value}'
            },
            // 左轴的横向参考线使用红色系
            splitLine: {
              show: true,
              lineStyle: {
                color: 'rgba(209, 74, 97, 0.15)', // 红色，15%透明度
                width: 1,
                type: 'solid'
              }
            }
          },
          {
            type: 'value',
            name: '存储文件数(个)',
            position: 'right',
            // 右轴使用1.8倍最大值，与左轴形成更大的分离度
            max: function(value: any) {
              return Math.ceil(value.max * 1.8);
            },
            axisLine: {
              show: true,
              lineStyle: {
                color: '#675bba'
              }
            },
            axisLabel: {
              formatter: '{value}'
            },
            // 右轴的横向参考线使用紫色系
            splitLine: {
              show: true,
              lineStyle: {
                color: 'rgba(103, 91, 186, 0.15)', // 紫色，15%透明度
                width: 1,
                type: 'dashed' // 使用虚线进一步区分
              }
            }
          }
        ],
        series: [
          {
            name: '存储总量',
            type: 'line',
            yAxisIndex: 0,
            data: storageChartData.validDataEndIndex !== undefined
              ? storageChartData.dataTotal.map((value, index) =>
                  index <= (storageChartData.validDataEndIndex ?? storageChartData.dataTotal.length - 1) ? value : null
                )
              : storageChartData.dataTotal,
            markPoint: {
              data: markPointDataTotal,
              label: {
                show: true,
                fontSize: 12,
                fontWeight: 'bold',
                color: '#fff',
                backgroundColor: 'transparent',
                padding: [6, 8],
                borderRadius: 3,
                textShadow: '1px 1px 2px rgba(255,255,255,0.8)',
                // 使用TypeScript类型注解，避免params隐式any类型
                formatter: function(params: { data: { yAxis: number } }) {
                  const value = params.data.yAxis;
                  if (value >= 10000) {
                    return (value / 1000).toFixed(1) + 'K';
                  } else if (value >= 1000) {
                    return (value / 1000).toFixed(2) + 'K';
                  }
                  return value.toString();
                }
              },
              symbolSize: 70,
              itemStyle: {
                color: '#d14a61',
                borderColor: '#fff',
                borderWidth: 2
              }
            },
            itemStyle: {
              color: '#d14a61'
            },
            lineStyle: {
              width: 2
            },
            areaStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                {
                  offset: 0,
                  color: 'rgba(209, 74, 97, 0.3)'
                },
                {
                  offset: 1,
                  color: 'rgba(209, 74, 97, 0.1)'
                }
              ])
            }
          },
          {
            name: '存储文件数',
            type: 'line',
            yAxisIndex: 1,
            data: storageChartData.validDataEndIndex !== undefined
              ? storageChartData.dataFile.map((value, index) =>
                  index <= (storageChartData.validDataEndIndex ?? storageChartData.dataFile.length - 1) ? value : null
                )
              : storageChartData.dataFile,
            markPoint: {
              data: markPointDataFile,
              label: {
                show: true,
                fontSize: 12,
                fontWeight: 'bold',
                color: '#fff',
                backgroundColor: 'transparent',
                padding: [6, 8],
                borderRadius: 3,
                textShadow: '1px 1px 2px rgba(255,255,255,0.8)',
                formatter: function(params: { data: { yAxis: number } }) {
                  const value = params.data.yAxis;
                  if (value >= 10000) {
                    return (value / 1000).toFixed(1) + 'K';
                  } else if (value >= 1000) {
                    return (value / 1000).toFixed(2) + 'K';
                  }
                  return value.toString();
                }
              },
              symbolSize: 70,
              itemStyle: {
                color: '#675bba',
                borderColor: '#fff',
                borderWidth: 2
              }
            },
            itemStyle: {
              color: '#675bba'
            },
            lineStyle: {
              width: 2
            },
            areaStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                {
                  offset: 0,
                  color: 'rgba(103, 91, 186, 0.3)'
                },
                {
                  offset: 1,
                  color: 'rgba(103, 91, 186, 0.1)'
                }
              ])
            }
          }
        ]
      };
      // 设置图表配置
      chart.setOption(option);
      
      // 监听窗口大小变化，调整图表大小
      const handleResize = () => {
        chart.resize();
      };
      window.addEventListener('resize', handleResize);
      
      // 返回清理函数
      return () => {
        window.removeEventListener('resize', handleResize);
      };
    }
  }, [isAuthenticated, storageChartData, dateType, storageUnit, chartLoading]);

  // 模拟数据生成函数 - 增强数据变化的明显性
  const generateMockSyncSpeed = () => {
    // 生成一个随机值，但保持一定的连续性，增加变化幅度
    const getRandomSpeed = (prevSpeed: number, baseLine: number) => {
      // 确保最小值不会太小，避免曲线贴近底部
      const min = Math.max(5, prevSpeed * 0.6); 
      // 增加上限变化幅度，让波动更明显
      const max = prevSpeed * 1.4 + 10; 
      // 增加基线影响，让不同地面站的数据有差异化的趋势
      return Math.round(min + Math.random() * (max - min) + baseLine * 0.2);
    };

    // 获取上一次的速度值，如果没有则使用预定义的初始值
    const lastGRAS3 = syncSpeedData.GRAS3.length > 0 ? syncSpeedData.GRAS3[syncSpeedData.GRAS3.length - 1] : INITIAL_SPEED.GRAS3;
    const lastGRAS4 = syncSpeedData.GRAS4.length > 0 ? syncSpeedData.GRAS4[syncSpeedData.GRAS4.length - 1] : INITIAL_SPEED.GRAS4;
    const lastGRAS5 = syncSpeedData.GRAS5.length > 0 ? syncSpeedData.GRAS5[syncSpeedData.GRAS5.length - 1] : INITIAL_SPEED.GRAS5;

    // 提高突变概率，使图表变化更明显
    const shouldSpike = Math.random() < 0.15;
    
    // 创建三个地面站的模拟数据，增加差异化
    const mockData = {
      code: 200,
      stat_res: {},
      stat_speed: [
        {
          real_speed: shouldSpike ? Math.round(Math.random() * 150) : getRandomSpeed(lastGRAS3, 50),
          real_rate: Math.round(Math.random() * 100),
          fileName: shouldSpike ? `GRAS3_File_${Date.now()}.dat` : (lastGRAS3 > 0 ? "GRAS3_ongoing_transfer.dat" : ""),
          gras: "GRAS3"
        },
        {
          real_speed: shouldSpike ? Math.round(Math.random() * 120) : getRandomSpeed(lastGRAS4, 30),
          real_rate: Math.round(Math.random() * 100),
          fileName: shouldSpike ? `GRAS4_File_${Date.now()}.dat` : (lastGRAS4 > 0 ? "GRAS4_ongoing_transfer.dat" : ""),
          gras: "GRAS4"
        },
        {
          real_speed: shouldSpike ? Math.round(Math.random() * 100) : getRandomSpeed(lastGRAS5, 20),
          real_rate: Math.round(Math.random() * 100),
          fileName: shouldSpike ? `GRAS5_File_${Date.now()}.dat` : (lastGRAS5 > 0 ? "GRAS5_ongoing_transfer.dat" : ""),
          gras: "GRAS5"
        }
      ]
    };
    
    return mockData;
  };

  // 修改获取地面站数据同步实时速率函数
  const fetchSyncSpeed = async () => {
    if (!isAuthenticated) return; // 未登录不执行
    try {
      const response = USE_MOCK_SYNC_SPEED 
        ? generateMockSyncSpeed()
        : await getSyncSpeed();
      const currentTime = dayjs().format('HH:mm:ss');
      let newGRAS3 = 0, newGRAS4 = 0, newGRAS5 = 0;
      if (response.code === 200) {
        // 获取新速率
        newGRAS3 = response.stat_speed.find(item => item.gras === 'GRAS3')?.real_speed || 0;
        newGRAS4 = response.stat_speed.find(item => item.gras === 'GRAS4')?.real_speed || 0;
        newGRAS5 = response.stat_speed.find(item => item.gras === 'GRAS5')?.real_speed || 0;
      }
      setSyncSpeedData(prevData => {
        const MAX_DATA_POINTS = 10;
        return {
          timestamps: [...prevData.timestamps, currentTime].slice(-MAX_DATA_POINTS),
          GRAS3: [...prevData.GRAS3, newGRAS3].slice(-MAX_DATA_POINTS),
          GRAS4: [...prevData.GRAS4, newGRAS4].slice(-MAX_DATA_POINTS),
          GRAS5: [...prevData.GRAS5, newGRAS5].slice(-MAX_DATA_POINTS)
        };
      });
      // 触发自定义事件，通知模态框中的图表更新
      window.dispatchEvent(new Event('syncDataUpdated'));
    } catch (error) {
      // 网络异常时也推进时间点
      const currentTime = dayjs().format('HH:mm:ss');
      setSyncSpeedData(prevData => {
        const MAX_DATA_POINTS = 10;
        return {
          timestamps: [...prevData.timestamps, currentTime].slice(-MAX_DATA_POINTS),
          GRAS3: [...prevData.GRAS3, 0].slice(-MAX_DATA_POINTS),
          GRAS4: [...prevData.GRAS4, 0].slice(-MAX_DATA_POINTS),
          GRAS5: [...prevData.GRAS5, 0].slice(-MAX_DATA_POINTS)
        };
      });
    }
  };

  // 修改启动定时器函数，确保定时器每10秒获取一次数据
  const startSyncSpeedTimer = () => {
    // 先停止可能存在的定时器
    stopSyncSpeedTimer();
    // 先立即获取一次数据
    fetchSyncSpeed();
    // 设置定时器每10秒获取一次数据
    syncSpeedTimerRef.current = window.setInterval(fetchSyncSpeed, 10000);
  };

  // 修改停止定时器函数
  const stopSyncSpeedTimer = () => {
    if (syncSpeedTimerRef.current) {
      window.clearInterval(syncSpeedTimerRef.current);
      syncSpeedTimerRef.current = null;
    }
  };

  // 修改图表初始化函数，只初始化一次，不依赖syncSpeedData
  useEffect(() => {
    if (!isAuthenticated) return; // 未登录不执行
    // 地面站数据同步实时速率图表 - 只负责初始化
    if (dataDistributionChartRef.current) {
      // 如果已存在图表实例，则销毁它
      if (dataDistributionChartInstanceRef.current) {
        dataDistributionChartInstanceRef.current.dispose();
      }
      // 创建新的图表实例
      const chart = echarts.init(dataDistributionChartRef.current);
      dataDistributionChartInstanceRef.current = chart;
      
      // 设置初始图表配置（空数据）
      const option = {
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'cross'
          }
        },
        legend: {
          data: ['GRAS3', 'GRAS4', 'GRAS5'],
          right: 10,
          top: 0
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '8%',
          top: '15%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          boundaryGap: false,
          data: []
        },
        yAxis: {
          type: 'value',
          name: '速率(MB/s)',
          min: 0,
          max: 10,
          axisLabel: {
            formatter: '{value}'
          }
        },
        series: [
          {
            name: 'GRAS3',
            type: 'line',
            data: [],
            smooth: true,
            symbol: 'none',
            smoothMonotone: 'x',
            lineStyle: {
              width: 1,
              color: '#1890ff'
            },
            animation: false
          },
          {
            name: 'GRAS4',
            type: 'line',
            data: [],
            smooth: true,
            symbol: 'none',
            smoothMonotone: 'x',
            lineStyle: {
              width: 1,
              color: '#52c41a'
            },
            animation: false
          },
          {
            name: 'GRAS5',
            type: 'line',
            data: [],
            smooth: true,
            symbol: 'none',
            smoothMonotone: 'x',
            lineStyle: {
              width: 1,
              color: '#faad14'
            },
            animation: false
          }
        ]
      };
      
      chart.setOption(option);
      
      // 只启动一次定时器
      startSyncSpeedTimer();
      
      // 监听窗口大小变化，调整图表大小
      const handleResize = () => {
        chart.resize();
      };
      window.addEventListener('resize', handleResize);
      
      return () => {
        window.removeEventListener('resize', handleResize);
        stopSyncSpeedTimer();
        chart.dispose();
      };
    }
  }, [isAuthenticated]); // 只在组件挂载和认证状态改变时执行

  // 添加单独的useEffect来监听syncSpeedData变化并更新图表
  useEffect(() => {
    // 当syncSpeedData变化时，更新图表
    if (dataDistributionChartInstanceRef.current) {
      const { timestamps, GRAS3, GRAS4, GRAS5 } = syncSpeedData;
      
      // 检查是否所有数据都为0
      const hasValidData = GRAS3.some(v => v > 0) || GRAS4.some(v => v > 0) || GRAS5.some(v => v > 0);
      
      const option = {
        xAxis: {
          data: timestamps
        },
        yAxis: {
          max: hasValidData ? null : 10 // 无数据时设置固定最大值
        },
        series: [
          {
            name: 'GRAS3',
            data: GRAS3,
            lineStyle: {
              width: hasValidData ? 3 : 1
            },
            areaStyle: hasValidData ? {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: 'rgba(24, 144, 255, 0.3)' },
                { offset: 1, color: 'rgba(24, 144, 255, 0.1)' }
              ])
            } : null,
            animation: hasValidData,
            animationDuration: hasValidData ? 1000 : 0
          },
          {
            name: 'GRAS4',
            data: GRAS4,
            lineStyle: {
              width: hasValidData ? 3 : 1
            },
            areaStyle: hasValidData ? {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: 'rgba(82, 196, 26, 0.3)' },
                { offset: 1, color: 'rgba(82, 196, 26, 0.1)' }
              ])
            } : null,
            animation: hasValidData,
            animationDuration: hasValidData ? 1000 : 0
          },
          {
            name: 'GRAS5',
            data: GRAS5,
            lineStyle: {
              width: hasValidData ? 3 : 1
            },
            areaStyle: hasValidData ? {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: 'rgba(250, 173, 20, 0.3)' },
                { offset: 1, color: 'rgba(250, 173, 20, 0.1)' }
              ])
            } : null,
            animation: hasValidData,
            animationDuration: hasValidData ? 1000 : 0
          }
        ]
      };
      
      dataDistributionChartInstanceRef.current.setOption(option);
    }
  }, [syncSpeedData]);

  // 更新模态框中的图表函数
  const updateSyncModalChart = () => {
    if (syncModalChartInstanceRef.current && syncSpeedData.timestamps.length > 0) {
      console.log('更新模态框中的图表');
      const { timestamps, GRAS3, GRAS4, GRAS5 } = syncSpeedData;
      
      const option = {
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'cross'
          }
        },
        legend: {
          data: ['GRAS3', 'GRAS4', 'GRAS5'],
          right: 10,
          top: 10
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '8%',
          top: '15%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          boundaryGap: false,
          data: timestamps
        },
        yAxis: {
          type: 'value',
          name: '速率(MB/s)',
          min: 0,
          axisLabel: {
            formatter: '{value}'
          }
        },
        series: [
          {
            name: 'GRAS3',
            type: 'line',
            data: GRAS3,
            smooth: true,
            symbol: 'none', // 不显示数据点标记，使曲线更平滑
            smoothMonotone: 'x', // 保持x方向单调，曲线更自然
            lineStyle: {
              width: 3,
              color: '#1890ff' // 蓝色
            },
            areaStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: 'rgba(24, 144, 255, 0.3)' },
                { offset: 1, color: 'rgba(24, 144, 255, 0.1)' }
              ])
            },
            animation: true,
            animationDuration: 1000,
            animationEasing: 'cubicOut'
          },
          {
            name: 'GRAS4',
            type: 'line',
            data: GRAS4,
            smooth: true,
            symbol: 'none',
            smoothMonotone: 'x',
            lineStyle: {
              width: 3,
              color: '#52c41a' // 绿色
            },
            areaStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: 'rgba(82, 196, 26, 0.3)' },
                { offset: 1, color: 'rgba(82, 196, 26, 0.1)' }
              ])
            },
            animation: true,
            animationDuration: 1000,
            animationEasing: 'cubicOut'
          },
          {
            name: 'GRAS5',
            type: 'line',
            data: GRAS5,
            smooth: true,
            symbol: 'none',
            smoothMonotone: 'x',
            lineStyle: {
              width: 3,
              color: '#faad14' // 橙色
            },
            areaStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: 'rgba(250, 173, 20, 0.3)' },
                { offset: 1, color: 'rgba(250, 173, 20, 0.1)' }
              ])
            },
            animation: true,
            animationDuration: 1000,
            animationEasing: 'cubicOut'
          }
        ]
      };
      
      syncModalChartInstanceRef.current.setOption(option);
    }
  };

  // 修改更新同步速率图表函数，增加平滑效果
  const updateSyncSpeedChart = () => {
    if (dataDistributionChartInstanceRef.current) {
      const { timestamps, GRAS3, GRAS4, GRAS5 } = syncSpeedData;
      
      const option = {
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'cross'
          }
        },
        legend: {
          data: ['GRAS3', 'GRAS4', 'GRAS5'],
          right: 10,
          top: 0
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '8%',
          top: '15%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          boundaryGap: false,
          data: timestamps
        },
        yAxis: {
          type: 'value',
          name: '速率(MB/s)',
          min: 0,
          axisLabel: {
            formatter: '{value}'
          }
        },
        series: [
          {
            name: 'GRAS3',
            type: 'line',
            data: GRAS3,
            smooth: true,
            symbol: 'none', // 不显示数据点标记，使曲线更平滑
            smoothMonotone: 'x', // 保持x方向单调，曲线更自然
            lineStyle: {
              width: 3,
              color: '#1890ff' // 蓝色
            },
            areaStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: 'rgba(24, 144, 255, 0.3)' },
                { offset: 1, color: 'rgba(24, 144, 255, 0.1)' }
              ])
            },
            animation: true,
            animationDuration: 1000,
            animationEasing: 'cubicOut'
          },
          {
            name: 'GRAS4',
            type: 'line',
            data: GRAS4,
            smooth: true,
            symbol: 'none',
            smoothMonotone: 'x',
            lineStyle: {
              width: 3,
              color: '#52c41a' // 绿色
            },
            areaStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: 'rgba(82, 196, 26, 0.3)' },
                { offset: 1, color: 'rgba(82, 196, 26, 0.1)' }
              ])
            },
            animation: true,
            animationDuration: 1000,
            animationEasing: 'cubicOut'
          },
          {
            name: 'GRAS5',
            type: 'line',
            data: GRAS5,
            smooth: true,
            symbol: 'none',
            smoothMonotone: 'x',
            lineStyle: {
              width: 3,
              color: '#faad14' // 橙色
            },
            areaStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: 'rgba(250, 173, 20, 0.3)' },
                { offset: 1, color: 'rgba(250, 173, 20, 0.1)' }
              ])
            },
            animation: true,
            animationDuration: 1000,
            animationEasing: 'cubicOut'
          }
        ]
      };
      
      dataDistributionChartInstanceRef.current.setOption(option);
    }
  };

  // 当模态框打开时初始化模态框中的图表
  useEffect(() => {
    if (!isAuthenticated) return; // 未登录不执行
    if (syncModalChartRef.current) {
      // 没有数据时不渲染
      if (syncSpeedData.timestamps.length === 0) return;
      // 清理之前的图表实例
      if (syncModalChartInstanceRef.current) {
        syncModalChartInstanceRef.current.dispose();
      }
      
      // 创建新的图表实例
      const chart = echarts.init(syncModalChartRef.current);
      syncModalChartInstanceRef.current = chart;
      
      // 设置初始数据
      const option = {
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'cross'
          },
          position: (pos: any, params: any, dom: any, rect: any, size: any) => {
            // 获取鼠标位置
            const mouseX = pos[0];
            const mouseY = pos[1];
            
            // 获取tooltip内容的高度
            const tooltipHeight = size.contentSize[1];
            
            // 计算tooltip的显示位置
            let x = mouseX;
            let y = mouseY - tooltipHeight - 10;
            
            // 检测是否超出图表边界
            if (y < 0) {
              y = mouseY + 10;
            }
            
            // 检测是否有重叠
            const overlapping = params.some((param: any, index: number) => {
              const nextParam = params[index + 1];
              if (nextParam) {
                const diff = Math.abs(param.dataIndex - nextParam.dataIndex);
                return diff <= 1;
              }
              return false;
            });
            
            // 如果有重叠，错开显示
            if (overlapping) {
              y = mouseY - tooltipHeight / 2;
            }
            
            return [x, y];
          },
          formatter: (params: any) => {
            // 自定义tooltip内容
            let tooltipContent = '';
            params.forEach((param: any) => {
              const { name, seriesName, value } = param;
              tooltipContent += `
                <div style="background-color: ${param.color}; color: #fff; padding: 4px 8px; border-radius: 4px; margin-bottom: 4px;">
                  <span style="font-weight: bold;">${seriesName}</span>: ${value} MB/s
                </div>
              `;
            });
            return tooltipContent;
          }
        },
        legend: {
          data: ['GRAS3', 'GRAS4', 'GRAS5'],
          right: 10,
          top: 10
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '8%',
          top: '15%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          boundaryGap: false,
          data: syncSpeedData.timestamps
        },
        yAxis: {
          type: 'value',
          name: '速率(MB/s)',
          min: 0,
          axisLabel: {
            formatter: '{value}'
          }
        },
        series: [
          {
            name: 'GRAS3',
            type: 'line',
            data: syncSpeedData.GRAS3,
            smooth: true,
            symbol: 'none',
            lineStyle: {
              width: 3,
              color: '#1890ff'
            },
            areaStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: 'rgba(24, 144, 255, 0.3)' },
                { offset: 1, color: 'rgba(24, 144, 255, 0.1)' }
              ])
            }
          },
          {
            name: 'GRAS4',
            type: 'line',
            data: syncSpeedData.GRAS4,
            smooth: true,
            symbol: 'none',
            lineStyle: {
              width: 3,
              color: '#52c41a'
            },
            areaStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: 'rgba(82, 196, 26, 0.3)' },
                { offset: 1, color: 'rgba(82, 196, 26, 0.1)' }
              ])
            }
          },
          {
            name: 'GRAS5',
            type: 'line',
            data: syncSpeedData.GRAS5,
            smooth: true,
            symbol: 'none',
            lineStyle: {
              width: 3,
              color: '#faad14'
            },
            areaStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: 'rgba(250, 173, 20, 0.3)' },
                { offset: 1, color: 'rgba(250, 173, 20, 0.1)' }
              ])
            }
          }
        ]
      };
      
      chart.setOption(option);
      
      // 监听窗口大小变化
      const handleResize = () => {
        chart.resize();
      };
      window.addEventListener('resize', handleResize);
      
      return () => {
        window.removeEventListener('resize', handleResize);
        if (syncModalChartInstanceRef.current) {
          syncModalChartInstanceRef.current.dispose();
          syncModalChartInstanceRef.current = null;
        }
      };
    }
  }, [isAuthenticated, syncSpeedData]);

  dayjs.locale('zh-cn');

  // 2. 新增useEffect，组件挂载时获取今日数据
  useEffect(() => {
    if (!isAuthenticated) return; // 未登录不执行
    // 获取今日日期
    const today = dayjs().format('YYYY-MM-DD');
    // 调用接口查今日数据
    getDataArchivingStats({
      sd: today,
      ed: today,
      task: 'ALL'
    }).then(res => {
      if (res.code === 200 && Array.isArray(res.data)) {
        // 累加今日所有数据量和文件数
        let accumulatedSizeInBytes = 0;
        let totalFile = 0;
        res.data.forEach(item => {
          accumulatedSizeInBytes += item.fz; // 假设fz直接是字节单位
          totalFile += parseInt(item.ft);
        });
        // 转换为字节后格式化
        setTodayArchiveSizeRaw(accumulatedSizeInBytes);
        setTodayArchiveFileCount(totalFile);
      } else {
        setTodayArchiveSizeRaw(0);
        setTodayArchiveFileCount(0);
      }
    }).catch(() => {
      setTodayArchiveSizeRaw(0);
      setTodayArchiveFileCount(0);
    });
  }, [isAuthenticated]);

  // 新增：根据任务类型获取对应的中文名称
  const getTaskTypeName = (taskType: string) => {
    const typeMap: Record<string, string> = {
      'DATA_ARCHIVING': '归档',
      'D4': '调用',
      'DATA_BACKUP': '备份',
      'DATA_RELEASE': '发布'
    };
    return typeMap[taskType] || taskType;
  };

  // 如果未登录，返回空内容
  if (!isAuthenticated) {
    return <div style={{ height: '100vh' }}></div>;
  }
  
  return (
    <ConfigProvider locale={zhCN}>
      <div className="dashboard-container">
        <div className="dashboard-content">
          <div className="left-panel">
            <div className="card data-overview">
              <div className="card-header">
                <span>数据归档</span>
                <div>
                  <button className="export-btn" onClick={handleExportReport} disabled={exportLoading}>
                    {exportLoading ? '导出中...' : '导出报表'}
                  </button>
                  <button
                    className={systemDiskBtnClass}
                    style={{ marginLeft: 8, lineHeight: 1.2, whiteSpace: 'pre-line', padding: '6px 12px' }}
                    onClick={() => setShowSystemDiskModal(true)}
                  >
                    业务文件系统
                    <br />
                    磁盘空间
                  </button>
                </div>
              </div>
              <div className="card-body">
                 {/* data-metrics 和 task-filter 合并为一行 */}
                 <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', marginBottom: 12 }}>
                   <div style={{ flex: '1 1 auto' }}>
                     <div className="data-metrics">
                       <div className="metric-item">
                         <div className="metric-icon green">
                           <DatabaseOutlined style={{ fontSize: 28 }} />
                         </div>
                         <div className="metric-info">
                           {/* 3. 用状态替换原有静态数据 */}
                           <div className="metric-value">{formatDataSize(todayArchiveSizeRaw)}</div>
                           <div className="metric-label">今日存档数据量</div>
                         </div>
                       </div>
                       <div className="metric-item">
                         <div className="metric-icon orange">
                           <FileOutlined style={{ fontSize: 28 }} />
                         </div>
                         <div className="metric-info">
                           <div className="metric-value">{formatFileCount(todayArchiveFileCount)}个</div>
                           <div className="metric-label">今日存档文件数</div>
                         </div>
                       </div>
                     </div>
                     <div className="date-type-switch" style={{ display: 'flex', justifyContent: 'flex-start', margin: '8px 0 0 0' }}>
                       <span
                         className={dateType === 'month' ? 'date-type-item active' : 'date-type-item'}
                         onClick={() => setDateType('month')}
                       >
                         当月
                       </span>
                       <span
                         className={dateType === 'year' ? 'date-type-item active' : 'date-type-item'}
                         onClick={() => setDateType('year')}
                       >
                         当年
                       </span>
                     </div>
                   </div>
                   <div className="task-filter" style={{ marginLeft: 15, flex: '1 1 auto' }}>
                     <div style={{ marginBottom: 6, display: 'flex', flexDirection: 'column', alignItems: 'flex-end' }}>
                       <div className="task-type" style={{ display: 'flex', justifyContent: 'flex-end', flexWrap: 'wrap', gap: 4 }}>
                         {TASKS.map(task => (
                           <span
                             key={task}
                             className={`type-item${selectedTasks.includes(task) ? ' active' : ''}`}
                             onClick={() => {
                               setSelectedTasks(selectedTasks =>
                                 selectedTasks.includes(task)
                                   ? selectedTasks.filter(t => t !== task)
                                   : [...selectedTasks, task]
                               );
                             }}
                             style={{ fontSize: 12, padding: '2px 8px', height: 24, lineHeight: '20px' }}
                           >
                             {task}
                           </span>
                         ))}
                         <span
                           className={`type-item${selectedTasks.length === TASKS.length ? ' active' : ''}`}
                           onClick={() => {
                             setSelectedTasks(selectedTasks.length === TASKS.length ? [] : [...TASKS]);
                           }}
                           style={{ fontSize: 12, padding: '2px 8px', height: 24, lineHeight: '20px' }}
                         >
                           全选
                         </span>
                       </div>
                     </div>
                     <div className="date-filter" style={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center', flexWrap: 'wrap', gap: 8 }}>
                       <div
                         className={`date-filter-item ${activeTimeMode === 'year' ? 'active' : 'inactive'}`}
                         style={{
                           display: 'flex',
                           alignItems: 'center',
                           padding: '8px 12px',
                           borderRadius: '6px',
                           cursor: 'pointer',
                           backgroundColor: activeTimeMode === 'year' ? '#e6f7ff' : 'transparent',
                           border: activeTimeMode === 'year' ? '1px solid #91d5ff' : '1px solid transparent',
                           opacity: activeTimeMode === 'year' ? 1 : 0.6,
                           transition: 'all 0.3s ease',
                           minHeight: '36px',
                           minWidth: '140px'
                         }}
                         onClick={() => switchTimeMode('year')}
                       >
                         <span style={{ marginRight: 4, fontSize: 12 }}>年份：</span>
                         <Select
                           value={selectedYear}
                           style={{ width: 80 }}
                           disabled={activeTimeMode !== 'year'}
                           onChange={(value) => {
                             // 确保输入的是有效年份
                             const year = parseInt(String(value));
                             if (!isNaN(year) && year >= 1900 && year <= 2100) {
                               setSelectedYear(year);
                             }
                           }}
                           options={defaultYearOptions.map(y => ({ value: y, label: String(y) }))}
                           size="small"
                           showSearch
                           filterOption={(input, option) =>
                             String(option?.label || '').includes(input) ||
                             String(option?.value || '').includes(input)
                           }
                           onSearch={(value) => {
                             // 允许用户输入年份数字
                             const year = parseInt(value);
                             if (!isNaN(year) && value.length === 4 && year >= 1900 && year <= 2100) {
                               setSelectedYear(year);
                             }
                           }}
                           placeholder="输入年份"
                           allowClear={false}
                         />
                       </div>
                       <div
                         className={`date-filter-item ${activeTimeMode === 'custom' ? 'active' : 'inactive'}`}
                         style={{
                           display: 'flex',
                           alignItems: 'center',
                           padding: '8px 12px',
                           borderRadius: '6px',
                           cursor: 'pointer',
                           backgroundColor: activeTimeMode === 'custom' ? '#e6f7ff' : 'transparent',
                           border: activeTimeMode === 'custom' ? '1px solid #91d5ff' : '1px solid transparent',
                           opacity: activeTimeMode === 'custom' ? 1 : 0.6,
                           transition: 'all 0.3s ease',
                           minHeight: '36px',
                           minWidth: '280px'
                         }}
                         onClick={() => switchTimeMode('custom')}
                       >
                         <span style={{ marginRight: 4, fontSize: 12 }}>自定义：</span>
                         <RangePicker
                           value={archiveChartDateRange}
                           disabled={activeTimeMode !== 'custom'}
                           onChange={range => { setArchiveChartDateRange(range ? range : [null, null]); }}
                           format="YYYY-MM-DD"
                           style={{ width: 220 }}
                           size="small"
                         />
                       </div>
                     </div>
                   </div>
                 </div>
                 
                 <div ref={dataStorageChartRef} className="chart-container">
                   {chartLoading && (
                     <div style={{ 
                       position: 'absolute', 
                       top: '50%', 
                       left: '50%', 
                       transform: 'translate(-50%, -50%)',
                       background: 'rgba(255, 255, 255, 0.7)',
                       padding: '10px 20px',
                       borderRadius: '4px'
                     }}>
                       数据加载中...
                     </div>
                   )}
                 </div>
                 

              </div>
            </div>
          </div>
          <div className="right-panel">
            <div className="card data-distribution">
              <div className="card-header">
                <span>数据发布</span>
                <button className="more-btn" onClick={() => {
                  setReleaseDetailYear(currentYear);
                  setShowPublishModal(true);
                  fetchDataReleaseByYear(currentYear);
                }}>查看更多</button>
              </div>
              <div className="card-body">
                <Spin spinning={releaseLoading} size="small">
                  <div className="data-summary">
                    <div className="summary-card">
                      <div className="summary-value">{releaseCount}</div>
                      <div className="summary-label">本月数据发布次数</div>
                    </div>
                    <div className="summary-card">
                      <div className="summary-value">{formatDataSize(releaseSizeBytes)}</div>
                      <div className="summary-label">数据量</div>
                    </div>
                    <div className="summary-card">
                      <div className="summary-value">{formatFileCount(releaseFileCount)}</div>
                      <div className="summary-label">文件数(个)</div>
                    </div>
                  </div>
                </Spin>
              </div>
            </div>
            <div className="card realtime-sync">
              <div className="card-header">
                <span>地面站数据同步实时速率</span>
                <button
                  className="more-btn"
                  onClick={() => {
                    const syncSoftwareUrl = import.meta.env.VITE_SYNC_SOFTWARE_URL;
                    window.open(syncSoftwareUrl, '_blank');
                  }}
                >
                  打开软件
                </button>
              </div>
              <div className="card-body">
                <div ref={dataDistributionChartRef} className="chart-container" style={{ height: '100%', minHeight: '250px' }}>
                  {syncSpeedData.timestamps.length === 0 && (
                    <div style={{textAlign: 'center', color: '#aaa', paddingTop: 80}}>暂无数据</div>
                  )}
                  {syncChartLoading && (
                    <div style={{ 
                      position: 'absolute', 
                      top: '50%', 
                      left: '50%', 
                      transform: 'translate(-50%, -50%)',
                      background: 'rgba(255, 255, 255, 0.7)',
                      padding: '8px 16px',
                      borderRadius: '4px'
                    }}>
                      数据加载中...
                    </div>
                  )}
                </div>
              </div>
            </div>
          </div>
        </div>
        <div className="full-width-row">
          <div className="card business-monitor">
            <div className="card-header">
              <span>业务运行状态监视</span>
            </div>
            <div className="card-body">
              <div className="business-type-filter" style={{ marginBottom: 16, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                <div>
                  <span
                    className={`filter-item${businessTypeFilter === '' ? ' active' : ''}`}
                    onClick={() => { setBusinessTypeFilter(''); }}
                  >
                    全部 <span style={{ color: '#1890ff' }}>({stats.totalCount})</span>
                  </span>
                  <span
                    className={`filter-item${businessTypeFilter === 'DATA_ARCHIVING' ? ' active' : ''}`}
                    onClick={() => { setBusinessTypeFilter('DATA_ARCHIVING'); }}
                    style={{ marginLeft: 24 }}
                  >
                    数据归档 <span style={{ color: '#1890ff' }}>({stats.archiveCount})</span>
                  </span>
                  <span
                    className={`filter-item${businessTypeFilter === 'D4' ? ' active' : ''}`}
                    onClick={() => { setBusinessTypeFilter('D4'); }}
                    style={{ marginLeft: 24 }}
                  >
                    数据调用 <span style={{ color: '#1890ff' }}>({stats.callCount})</span>
                  </span>
                  <span
                    className={`filter-item${businessTypeFilter === 'DATA_BACKUP' ? ' active' : ''}`}
                    onClick={() => { setBusinessTypeFilter('DATA_BACKUP'); }}
                    style={{ marginLeft: 24 }}
                  >
                    数据备份 <span style={{ color: '#1890ff' }}>({stats.backupCount})</span>
                  </span>
                  <span
                    className={`filter-item${businessTypeFilter === 'DATA_RELEASE' ? ' active' : ''}`}
                    onClick={() => { setBusinessTypeFilter('DATA_RELEASE'); }}
                    style={{ marginLeft: 24 }}
                  >
                    数据发布 <span style={{ color: '#1890ff' }}>({stats.publishCount})</span>
                  </span>
                </div>
                <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
                  {/* 移除外部发起方Select，只保留表头筛选 */}
                  <Select
                    style={{ width: 100 }}
                    value={statusFilter}
                    onChange={value => { setStatusFilter(value); }}
                    options={[
                      { value: '全部', label: '全部' },
                      { value: '1', label: '成功' },
                      { value: '0', label: '运行中' },
                      { value: '-1', label: '失败' }
                    ]}
                    allowClear={false}
                    placeholder="状态"
                  />
                  <RangePicker
                    value={startTimeRange}
                    onChange={range => { 
                      setStartTimeRange(range ? range : [null, null]); 
                      // 日期范围变化需要重新从服务器请求数据
                    }}
                    format="YYYY-MM-DD"
                    style={{ width: 240 }}
                    disabledDate={(current: dayjs.Dayjs | null) => {
                      const end = dayjs();
                      const start = end.subtract(29, 'day');
                      return !!current && (current.isBefore(start.startOf('day')) || current.isAfter(end.endOf('day')));
                    }}
                    onCalendarChange={(dates: (dayjs.Dayjs | null)[] | null) => {
                      if (dates && dates[0] && dates[1]) {
                        const diff = dates[1].diff(dates[0], 'day');
                        if (diff > 29) {
                          message.warning('最多只能选择30天区间');
                          setStartTimeRange([dates[0], dates[0].add(29, 'day').endOf('day')]);
                        }
                      }
                    }}
                  />
                  <Button onClick={() => { 
                    setStatusFilter('全部'); 
                    setBusinessTypeFilter(''); 
                    setStartTimeRange([null, null]); 
                    // 重置后重新请求数据
                    setTimeout(() => fetchBusinessData(), 0);
                  }}>重置</Button>
                </div>
              </div>
              <div className="table-container">
                <SwitchTransition>
                  <CSSTransition
                    key={businessTypeFilter + initiatorFilter + statusFilter + (startTimeRange[0]?.toString() || '') + (startTimeRange[1]?.toString() || '') + currentPage + pageSize}
                    timeout={400}
                    classNames="fade"
                    nodeRef={tableNodeRef}
                  >
                    <div ref={tableNodeRef}>
                      <Table
                        loading={loading}
                        bordered
                        rowClassName={(_, index) => (index % 2 === 0 ? 'even-row' : 'odd-row')}
                        columns={[
                          { 
                            title: '序号', 
                            dataIndex: 'key', 
                            key: 'key', 
                            width: 60,
                            render: (_: any, __: any, index: number) => (currentPage - 1) * pageSize + index + 1
                          },
                          { title: '任务ID', dataIndex: 'taskId', key: 'taskId' },
                          { title: '任务类型', dataIndex: 'taskType', key: 'taskType', render: (text) => {
                            const typeMap: Record<string, string> = {
                              'DATA_ARCHIVING': '数据归档',
                              'D4': '数据调用',
                              'DATA_BACKUP': '数据备份',
                              'DATA_RELEASE': '数据发布'
                            };
                            return typeMap[text] || text;
                          }},
                          // 发起方表头筛选
                          {
                            title: '发起方',
                            dataIndex: 'initiator',
                            key: 'initiator',
                            filters: (businessTypeFilter === '' || businessTypeFilter === 'DATA_ARCHIVING')
                              ? allInitiators.map(i => ({ text: i, value: i }))
                              : undefined,
                            filterMultiple: false,
                          },
                          { title: '开始时间（UTC）', dataIndex: 'startTime', key: 'startTime', sorter: true, sortOrder: sortField === 'startTime' ? sortOrder : null, },
                          { title: '结束时间', dataIndex: 'endTime', key: 'endTime', sorter: true, sortOrder: sortField === 'endTime' ? sortOrder : null, },
                          { title: '数据量', dataIndex: 'dataSize', key: 'dataSize', render: (dataSize) => (
                            <span>
                              <span style={{ color: '#52c41a', fontWeight: 500 }}>
                                {formatDataSize(dataSize.success || 0)}
                              </span>
                              <span style={{ color: '#1890ff', fontWeight: 500 }}>
                                {' / ' + formatDataSize(dataSize.total || 0)}
                              </span>
                            </span>
                          ) },
                          { title: '文件数(个)', dataIndex: 'fileCount', key: 'fileCount', render: (fileCount) => (
                            <span>
                              <span style={{ color: '#52c41a', fontWeight: 500 }}>{formatFileCount(fileCount.success || 0)}</span>
                              <span style={{ color: '#f5222d', margin: '0 4px', fontWeight: 500 }}>/ {formatFileCount(fileCount.fail || 0)}</span>
                              <span style={{ color: '#1890ff', fontWeight: 500 }}>/ {formatFileCount(fileCount.total || 0)}</span>
                            </span>
                          ) },
                          // 状态表头筛选（移动到文件数后面）
                          {
                            title: '状态',
                            dataIndex: 'status',
                            key: 'status',
                            filters: [
                              { text: '全部', value: '全部' },
                              { text: '成功', value: '成功' },
                              { text: '运行中', value: '运行中' },
                              { text: '失败', value: '失败' }
                            ],
                            filterMultiple: false,
                            render: (text) => {
                              if (text === '成功') return <span className="status-tag status-success">成功</span>;
                              if (text === '运行中') return <span className="status-tag status-running">运行中</span>;
                              return <span className="status-tag status-error">失败</span>;
                            }
                          },
                          // 移除失败原因列
                          // { title: '失败原因', dataIndex: 'failReason', key: 'failReason' },
                          { title: '详情', dataIndex: 'detail', key: 'detail', render: (_, record) => <a href="#" className="detail-link" onClick={async (e) => {
                            e.preventDefault();

                            // 如果是数据发布类型，打开发布详情弹窗
                            if (record.taskType === 'DATA_RELEASE') {
                              // 从rflag中提取release_task_id
                              // rflag格式: RELEASE_DATA_133 -> 提取133
                              const rflag = record.rawData?.rflag || '';
                              const matches = rflag.match(/RELEASE_DATA_(\d+)/);
                              const releaseTaskId = matches ? matches[1] : null;

                              if (!releaseTaskId) {
                                message.error('无法获取发布任务ID');
                                console.error('无法从rflag提取ID:', rflag);
                                return;
                              }

                              setSelectedReleaseTaskId(releaseTaskId);
                              setShowReleaseDetailModal(true);
                              return;
                            }

                            // 其他类型的详情处理
                            setSelectedBusiness({
                              taskId: record.taskId,
                              taskType: record.taskType, // 新增：保存任务类型
                              initiator: record.initiator,
                              endTime: record.endTime,
                              dataSize: typeof record.dataSize === 'object' ?
                                `${record.dataSize.success?.toFixed(2) || 0}/${record.dataSize.total?.toFixed(2) || 0}` :
                                record.dataSize,
                              fileCount: typeof record.fileCount === 'object' ?
                                `${record.fileCount.success || 0}/${record.fileCount.fail || 0}/${record.fileCount.total || 0}` :
                                record.fileCount,
                              status: record.status,
                              failReason: record.failReason
                            });
                            setExportModalVisible(true);
                            setSelectedBusinessFiles(exportFileData.filter(f => f.taskType === record.taskType));
                            // 新增：请求XML详情
                            setXmlDetailLoading(true);
                            setXmlDetailError(null);
                            setXmlDetailData(null);
                            setXmlRawString('');
                            setXmlCollapseOpen(false);
                            try {
                              // 这里假设record.rawData.rxml_path为文件路径
                              const filePath = record.rawData?.rf_result_xml || record.rawData?.rxml_path;
                              console.log('准备请求XML文件路径:', filePath, '原始数据:', record.rawData);
                              
                              // 保存XML文件路径用于链接显示
                              setXmlFilePath(filePath || '');
                              
                              if (!filePath) {
                                console.error('未找到XML文件路径', record.rawData);
                                throw new Error('未找到XML文件路径');
                              }
                              
                              const res = await fetch(`${import.meta.env.VITE_API_BASE_URL}/-/bin.dataArchiving.get_result_xml`, {
                                method: 'POST',
                                headers: {
                                  'Content-Type': 'application/json',
                                  'token': localStorage.getItem('token') || '' // 新增token
                                },
                                body: JSON.stringify({ file: filePath })
                              });
                              
                              const data = await res.json();
                              console.log('获取XML响应:', data);
                              
                              if (data.code !== 200) {
                                console.error('接口返回错误', data);
                                throw new Error('接口返回错误: ' + (data.message || '未知错误'));
                              }
                              
                              if (!data.data) {
                                console.error('接口返回数据为空', data);
                                throw new Error('接口返回数据为空');
                              }
                              
                              setXmlRawString(data.data);
                              
                              // 解析XML
                              try {
                                console.log('准备解析XML:', data.data.substring(0, 100) + '...');
                                const parser = new XMLParser({ 
                                  ignoreAttributes: false, 
                                  attributeNamePrefix: '', 
                                  isArray: (name) => name === 'File' 
                                });
                                const parsed = parser.parse(data.data);
                                console.log('解析XML结果:', parsed);
                                setXmlDetailData(parsed);
                              } catch (parseErr: any) {
                                console.error('XML解析失败', parseErr);
                                throw new Error('XML解析失败: ' + parseErr.message);
                              }
                            } catch (err: any) {
                              console.error('获取详情失败', err);
                              setXmlDetailError(err.message || '获取详情失败');
                              message.error('获取详情失败: ' + err.message);
                            } finally {
                              setXmlDetailLoading(false);
                            }
                          }}>查看</a> },
                        ]}
                        dataSource={businessData}
                        pagination={{
                          current: currentPage,
                          pageSize: pageSize,
                          total: businessTotal,
                          showSizeChanger: true,
                          pageSizeOptions: ['5', '10', '20', '50'],
                          showTotal: (total) => `共 ${total} 条`,
                          onChange: (page, size) => {
                            setCurrentPage(page);
                            setPageSize(size || 10);
                          },
                        }}
                        style={{ width: '100%' }}
                        onChange={(pagination, filters, sorter) => {
                          // 只处理表头排序和发起方、状态筛选
                          if (filters && filters.initiator) {
                            setInitiatorFilter(String(filters.initiator[0] || '全部'));
                            setCurrentPage(1); // 切换筛选时重置到第一页
                          }
                          if (filters && filters.status) {
                            setStatusFilter(String(filters.status[0] || '全部'));
                            setCurrentPage(1);
                          }
                          if (sorter && typeof sorter === 'object' && 'field' in sorter) {
                            // 只允许开始时间和结束时间排序
                            if (sorter.field === 'startTime' || sorter.field === 'endTime') {
                              setSortField(sorter.field as string);
                              setSortOrder(sorter.order as 'ascend' | 'descend' | null);
                            } else {
                              setSortField('');
                              setSortOrder(null);
                            }
                          }
                        }}
                      />
                    </div>
                  </CSSTransition>
                </SwitchTransition>
              </div>
            </div>
          </div>
        </div>
        
        {/* 导出选项弹窗 */}
        <Modal
          title="导出报表"
          open={exportOptionsModalVisible}
          onOk={handleExportConfirm}
          onCancel={handleExportOptionsCancel}
          okText="确认导出"
          cancelText="取消"
          width={400}
        >
          <div style={{ padding: '20px 0' }}>
            <p style={{ marginBottom: '16px', color: '#666' }}>
              请选择导出报表的时间类型：
            </p>
            <Radio.Group 
              value={exportTimeType} 
              onChange={(e) => setExportTimeType(e.target.value)}
              style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}
            >
              <Radio value="archive">按归档时间</Radio>
              <Radio value="collection">按采集时间</Radio>
            </Radio.Group>
          </div>
        </Modal>

        {/* 导出报表弹窗 */}
        <Modal
          title={`${getTaskTypeName(selectedBusiness?.taskType || '')}详情`}
          open={exportModalVisible}
          onCancel={handleExportModalCancel}
          width={1400}
          footer={null}
          className="export-detail-modal"
        >
          <div className="export-detail-container">
            <div className="export-detail-header">
              <div className="detail-grid">
                <div className="detail-item">
                  <span className="detail-label">任务ID:</span>
                  <span className="detail-value">{selectedBusiness?.taskId || '--'}</span>
                </div>
                <div className="detail-item">
                  <span className="detail-label">请求方:</span>
                  <span className="detail-value">{selectedBusiness?.initiator || '--'}</span>
                </div>
                <div className="detail-item">
                  <span className="detail-label">{getTaskTypeName(selectedBusiness?.taskType || '')}时间:</span>
                  <span className="detail-value">{selectedBusiness?.endTime || '--'}</span>
                </div>
                <div className="detail-item">
                  <span className="detail-label">{getTaskTypeName(selectedBusiness?.taskType || '')}数据量:</span>
                  <span className="detail-value">{selectedBusiness?.dataSize || '--'}</span>
                </div>
                <div className="detail-item">
                  <span className="detail-label">文件数:</span>
                  <span className="detail-value">{selectedBusiness?.fileCount || '--'}</span>
                </div>
                <div className="detail-item">
                  <span className="detail-label">状态:</span>
                  <span className="detail-value">{selectedBusiness?.status || '--'}</span>
                </div>
                <div className="detail-item">
                  <span className="detail-label">失败原因:</span>
                  <span className="detail-value">{selectedBusiness?.failReason || '--'}</span>
                </div>
                <div className="detail-item">
                  <span className="detail-label">原始XML:</span>
                  <span className="detail-value">
                    {xmlRawString ? (
                      <a
                        href="#"
                        onClick={e => {
                          e.preventDefault();
                          // 新开标签页并写入XML内容
                          const newWindow = window.open('', '_blank');
                          if (newWindow) {
                            newWindow.document.write(`
                              <html>
                                <head>
                                  <title>XML原文查看</title>
                                  <meta charset=\"utf-8\" />
                                  <style>
                                    body { margin: 0; padding: 16px; background: #f7f7f7; }
                                    pre { white-space: pre-wrap; word-break: break-all; font-size: 14px; background: #fff; padding: 16px; border-radius: 6px; box-shadow: 0 2px 8px #0001; }
                                  </style>
                                </head>
                                <body>
                                  <pre>${xmlRawString.replace(/</g, '&lt;').replace(/>/g, '&gt;')}</pre>
                                </body>
                              </html>
                            `);
                            newWindow.document.close();
                          }
                        }}
                        style={{ color: '#1890ff', textDecoration: 'underline', cursor: 'pointer' }}
                      >
                        查看XML文件
                      </a>
                    ) : '--'}
                  </span>
                </div>
              </div>
            </div>
            {/* XML详情区块 */}
            <div className="xml-detail-section">
              <h3 className="xml-detail-title">{getTaskTypeName(selectedBusiness?.taskType || '')}XML详情</h3>
              {xmlDetailLoading && <div className="loading-text">加载中...</div>}
              {xmlDetailError && <div className="error-text">{xmlDetailError}</div>}
              {!xmlDetailLoading && !xmlDetailError && xmlDetailData && (
                <div className="xml-content">
                  {(() => {
                    try {
                      const detail = xmlDetailData.DetailList || {};
                      const fileInfo = detail.FileInfo && (detail.FileInfo['SatID'] || detail.FileInfo['@_SatID'] || '-');
                      const fileType = detail.FileInfo && (detail.FileInfo['FileType'] || detail.FileInfo['@_FileType'] || '-');
                      const fileNum = detail.FileNum && (detail.FileNum['Total'] || detail.FileNum['@_Total'] || '-');
                      const fileSuccess = detail.FileNum && (detail.FileNum['Success'] || detail.FileNum['@_Success'] || '-');
                      const fileFail = detail.FileNum && (detail.FileNum['Failure'] || detail.FileNum['@_Failure'] || '-');
                      let failList: any[] = [];
                      let successList: any[] = [];
                      
                      // 判断是否为数据调用类型（D4），使用不同的解析逻辑
                      const isDataCall = selectedBusiness?.taskType === 'D4';
                      
                      if (isDataCall) {
                        // 数据调用类型：根据File标签的Flag属性来判断成功失败
                        const allFiles: any[] = [];
                        if (detail.FileList?.File) {
                          if (Array.isArray(detail.FileList.File)) {
                            allFiles.push(...detail.FileList.File);
                          } else {
                            allFiles.push(detail.FileList.File);
                          }
                        }
                        
                        // 根据Flag属性分类：1是成功，0是失败
                        allFiles.forEach((file: any) => {
                          const processedFile = {
                            ...file,
                            ...file['@_']
                          };
                          const flag = processedFile.Flag || processedFile['@_Flag'];
                          if (flag === '1' || flag === 1) {
                            successList.push(processedFile);
                          } else if (flag === '0' || flag === 0) {
                            failList.push({
                              ...processedFile,
                              ErrorMsg: processedFile.ErrorMsg || '-'
                            });
                          }
                        });
                      } else {
                        // 其他类型：使用原有的Success/Failure节点解析逻辑
                        if (detail.FileList?.Failure) {
                          if (Array.isArray(detail.FileList.Failure.File)) {
                            failList = detail.FileList.Failure.File.map((file: any) => ({
                              ...file,
                              ...file['@_'],
                              ErrorMsg: file.ErrorMsg || '-'
                            }));
                          } else if (detail.FileList.Failure.File) {
                            const file = detail.FileList.Failure.File;
                            failList = [{
                              ...file,
                              ...file['@_'],
                              ErrorMsg: file.ErrorMsg || '-'
                            }];
                          }
                        }
                        
                        if (detail.FileList?.Success) {
                          if (Array.isArray(detail.FileList.Success.File)) {
                            successList = detail.FileList.Success.File.map((file: any) => ({
                              ...file,
                              ...file['@_']
                            }));
                          } else if (detail.FileList.Success.File) {
                            const file = detail.FileList.Success.File;
                            successList = [{
                              ...file,
                              ...file['@_']
                            }];
                          }
                        }
                      }
                      return (
                        <div>
                          <div className="file-summary">
                            <span className="summary-item">卫星ID: <strong>{String(fileInfo)}</strong></span>
                            <span className="summary-item">文件类型: <strong>{String(fileType)}</strong></span>
                            <span className="summary-item">总数: <strong>{String(fileNum)}</strong></span>
                            <span className="summary-item success">成功: <strong>{String(fileSuccess)}</strong></span>
                            <span className="summary-item fail">失败: <strong>{String(fileFail)}</strong></span>
                          </div>
                          
                          {/* 只有失败文件数量大于0时才显示失败文件列表 */}
                          {failList.length > 0 && (
                            <div className="file-section">
                              <h4 className="section-title fail-title">{getTaskTypeName(selectedBusiness?.taskType || '')}失败文件列表</h4>
                              <Table
                                size="small"
                                bordered
                                scroll={{ x: 'max-content' }}
                                className="fail-files-table"
                                columns={[
                                  { title: '文件名', dataIndex: 'FileName', key: 'FileName', width: 200 },
                                  { title: '路径', dataIndex: 'Path', key: 'Path', width: 300 },
                                  { title: '时间', dataIndex: 'CDateTime', key: 'CDateTime', width: 150 },
                                  { title: '大小', dataIndex: 'size', key: 'size', width: 100 },
                                  { title: '错误信息', dataIndex: 'ErrorMsg', key: 'ErrorMsg', width: 200, render: (text) => <span className="error-msg">{text}</span> }
                                ]}
                                dataSource={failList.map((f: any, i: number) => ({ key: i, ...f }))}
                                pagination={false}
                              />
                            </div>
                          )}
                          
                          {/* 成功文件列表 */}
                          <div className="file-section">
                            <h4 className="section-title success-title">{getTaskTypeName(selectedBusiness?.taskType || '')}成功文件列表</h4>
                            {successList.length === 0 ? (
                              <div className="no-data">无成功文件</div>
                            ) : (
                              <Table
                                size="small"
                                bordered
                                scroll={{ x: 'max-content' }}
                                className="success-files-table"
                                columns={[
                                  { title: '文件名', dataIndex: 'FileName', key: 'FileName', width: 200 },
                                  { title: '路径', dataIndex: 'Path', key: 'Path', width: 300 },
                                  { title: '时间', dataIndex: 'CDateTime', key: 'CDateTime', width: 150 },
                                  { title: '大小', dataIndex: 'size', key: 'size', width: 100 }
                                ]}
                                dataSource={successList.map((f: any, i: number) => ({ key: i, ...f }))}
                                pagination={false}
                              />
                            )}
                          </div>
                        </div>
                      );
                    } catch (renderErr) {
                      return <div className="error-text">XML数据解析出错: {(renderErr as Error).message || '未知错误'}</div>;
                    }
                  })()}
                </div>
              )}
            </div>
          </div>
        </Modal>
        {/* 数据发布详情弹窗 */}
        <Modal
          title="数据发布详情"
          open={showPublishModal}
          onCancel={() => setShowPublishModal(false)}
          width={800}
          footer={[
            <Button key="close" onClick={() => setShowPublishModal(false)}>
              关闭
            </Button>
          ]}
        >
          <div style={{ marginBottom: 16 }}>
            <span style={{ marginRight: 8 }}>选择年份：</span>
            <Select
              value={releaseDetailYear}
              onChange={(value) => {
                setReleaseDetailYear(value);
                fetchDataReleaseByYear(value);
              }}
              style={{ width: 120 }}
            >
              {defaultYearOptions.map(year => (
                <Select.Option key={year} value={year}>
                  {year}年
                </Select.Option>
              ))}
            </Select>
          </div>

          <Spin spinning={releaseDetailLoading}>
            <div>
              <Table
                dataSource={releaseDetailData}
                rowKey="month"
                pagination={false}
                scroll={{ y: 400 }}
                columns={[
                  {
                    title: '月份',
                    dataIndex: 'month',
                    key: 'month',
                    width: 150,
                    align: 'center',
                  },
                  {
                    title: '发布次数',
                    dataIndex: 'publishCount',
                    key: 'publishCount',
                    width: 120,
                    align: 'center',
                  },
                  {
                    title: '文件数',
                    dataIndex: 'fileCount',
                    key: 'fileCount',
                    width: 120,
                    align: 'center',
                    render: (text) => formatFileCount(text)
                  },
                  {
                    title: '数据量',
                    dataIndex: 'dataSize',
                    key: 'dataSize',
                    width: 150,
                    align: 'center',
                  }
                ]}
              />
              {releaseDetailTotal && (
                <div className="ant-table ant-table-small" style={{
                  borderTop: '2px solid #1890ff',
                  backgroundColor: '#f0f5ff',
                  fontWeight: 500
                }}>
                  <table style={{ tableLayout: 'fixed', width: `calc(100% - ${scrollbarWidth}px)` }}>
                    <colgroup>
                      <col style={{ width: 150 }} />
                      <col style={{ width: 120 }} />
                      <col style={{ width: 120 }} />
                      <col style={{ width: 150 }} />
                    </colgroup>
                    <tbody className="ant-table-tbody">
                      <tr className="ant-table-row">
                        <td className="ant-table-cell" style={{ padding: '12px 16px', textAlign: 'center' }}>
                          {releaseDetailTotal.month}
                        </td>
                        <td className="ant-table-cell" style={{ padding: '12px 16px', textAlign: 'center' }}>
                          {releaseDetailTotal.publishCount}
                        </td>
                        <td className="ant-table-cell" style={{ padding: '12px 16px', textAlign: 'center' }}>
                          {formatFileCount(releaseDetailTotal.fileCount)}
                        </td>
                        <td className="ant-table-cell" style={{ padding: '12px 16px', textAlign: 'center' }}>
                          {releaseDetailTotal.dataSize}
                        </td>
                      </tr>
                    </tbody>
                  </table>
                </div>
              )}
              {releaseDetailData.length === 0 && !releaseDetailLoading && (
                <Empty
                  description="暂无数据"
                  style={{ margin: '40px 0' }}
                />
              )}
            </div>
          </Spin>
        </Modal>
        {/* 新增业务文件系统磁盘空间监视弹窗 */}
        <Modal
          title={
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', width: '100%' }}>
              <SettingOutlined className="modal-title-icon" style={{ marginRight: 8 }} />
              <span>业务文件系统磁盘空间</span>
            </div>
          }
          open={showSystemDiskModal}
          onCancel={() => setShowSystemDiskModal(false)}
          footer={null}
          width={Math.min(window.innerWidth * 0.9, 830)}
          centered
          className="disk-space-modal"
        >
          <div className="system-disk-container">
            {diskSpaceLoading ? (
              <div style={{ textAlign: 'center', padding: '40px' }}>
                <Spin tip="加载中..." />
              </div>
            ) : systemDisks.length > 0 ? (
              systemDisks.map(disk => (
                <div className="system-disk-item" key={disk.PATH}>
                  <div className="disk-info">
                    <div className="disk-name">{disk.NAME}</div>
                    <div className="disk-path">{disk.PATH}</div>
                  </div>
                  <div className="disk-progress-wrapper">
                    <div className="disk-progress-circle">
                      <CircularProgress percentage={disk.rate} />
                    </div>
                  </div>
                  {disk.ISMON === 1 && (
                    <button 
                      className="disk-clear-btn disk-clear-btn-large"
                      onClick={() => handleDiskClean(disk.PATH, disk.NAME)}
                    >
                      清理
                    </button>
                  )}
                </div>
              ))
            ) : (
              <Empty description="暂无磁盘空间数据" />
            )}
          </div>
        </Modal>
        {/* 批量导出进度弹窗 */}
        <Modal
          title="批量导出进度"
          open={exportProgressVisible}
          onCancel={() => {
            if (!isExporting) {
              setExportProgressVisible(false);
              setExportingTasks([]);
            }
          }}
          footer={[
            <Button
              key="close"
              onClick={() => {
                if (!isExporting) {
                  setExportProgressVisible(false);
                  setExportingTasks([]);
                }
              }}
              disabled={isExporting}
            >
              关闭
            </Button>
          ]}
          width={800}
          maskClosable={false}
        >
          <div style={{ marginBottom: '16px' }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '8px' }}>
              <span><strong>统计时间范围：</strong>{exportTimeRange}</span>
              <span><strong>导出任务数：</strong>{exportingTasks.length}</span>
            </div>
          </div>
          <Table
            className="export-progress-table"
            dataSource={exportingTasks.map((task, index) => ({
              key: index,
              taskName: task.taskName,
              status: task.status,
              progress: task.progress || 0,
              message: task.message
            }))}
            columns={[
              {
                title: '任务标号',
                dataIndex: 'taskName',
                key: 'taskName',
                width: 120,
                align: 'center'
              },
              {
                title: '导出状态',
                dataIndex: 'status',
                key: 'status',
                width: 120,
                align: 'center',
                render: (status: string, record: any) => {
                  if (status === 'waiting') {
                    return <Tag color="default">等待中</Tag>;
                  }
                  if (status === 'exporting') {
                    return (
                      <Tag color="processing">
                        <SyncOutlined spin /> 导出中
                      </Tag>
                    );
                  }
                  if (status === 'success') {
                    return <Tag color="success">导出成功</Tag>;
                  }
                  if (status === 'failed') {
                    return (
                      <Tooltip title={record.message}>
                        <Tag color="error">导出失败</Tag>
                      </Tooltip>
                    );
                  }
                  return null;
                }
              },
              {
                title: '导出进度',
                dataIndex: 'progress',
                key: 'progress',
                width: 200,
                align: 'center',
                render: (progress: number, record: any) => {
                  let strokeColor = '#1890ff';
                  if (record.status === 'success') strokeColor = '#52c41a';
                  if (record.status === 'failed') strokeColor = '#ff4d4f';
                  
                  return (
                    <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
                      <div style={{ 
                        width: '120px', 
                        height: '8px', 
                        backgroundColor: '#f0f0f0', 
                        borderRadius: '4px',
                        overflow: 'hidden'
                      }}>
                        <div style={{
                          width: `${progress}%`,
                          height: '100%',
                          backgroundColor: strokeColor,
                          transition: 'width 0.3s ease'
                        }} />
                      </div>
                      <span style={{ fontSize: '12px', color: '#666', minWidth: '35px' }}>
                        {progress}%
                      </span>
                    </div>
                  );
                }
              },
              {
                title: '操作结果',
                dataIndex: 'message',
                key: 'message',
                align: 'center',
                render: (message: string, record: any) => {
                  if (record.status === 'success') {
                    return (
                      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '4px' }}>
                        <CheckCircleFilled style={{ color: '#52c41a', fontSize: 16 }} />
                        <span style={{ color: '#52c41a' }}>下载完成</span>
                      </div>
                    );
                  }
                  if (record.status === 'failed') {
                    return (
                      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '4px' }}>
                        <CloseCircleFilled style={{ color: '#ff4d4f', fontSize: 16 }} />
                        <Tooltip title={message}>
                          <span style={{ color: '#ff4d4f', cursor: 'pointer' }}>导出失败</span>
                        </Tooltip>
                      </div>
                    );
                  }
                  if (record.status === 'exporting') {
                    return <span style={{ color: '#1890ff' }}>正在导出...</span>;
                  }
                  return <span style={{ color: '#999' }}>等待导出</span>;
                }
              }
            ]}
            pagination={false}
            size="small"
            style={{ marginTop: '8px' }}
          />
        </Modal>

        {/* 数据发布报告详情弹窗 */}
        <ReleaseDetailModal
          open={showReleaseDetailModal}
          onCancel={() => {
            setShowReleaseDetailModal(false);
            setSelectedReleaseTaskId(null);
          }}
          releaseTaskId={selectedReleaseTaskId}
        />
      </div>
    </ConfigProvider>
  );
};

export default Dashboard; 
